<template>
  <q-page v-if="canReadOrder" class="npc-page">
    <div class="ol-filter-bar npc-filter-bar">
      <div class="npc-filter-row">
        <q-input
          v-model="filters.search"
          class="npc-filter-input npc-search"
          dense
          filled
          clearable
          debounce="300"
          label="Arama (Maliyet No / Urun Kodu / Urun Adi / Aciklama)"
        >
          <template #append>
            <q-icon name="search" />
          </template>
        </q-input>

        <div class="ol-filter-actions npc-filter-actions">
          <q-btn
            label="Temizle"
            icon="clear"
            color="grey-7"
            flat
            :disable="loading"
            @click="clearFilters"
          />
          <q-btn
            label="Kolon Filtreleri"
            icon="filter_alt_off"
            color="grey-7"
            flat
            :disable="loading"
            @click="clearAllColumnFilters"
          />
          <q-btn
            label="Yenile"
            icon="refresh"
            color="primary"
            :loading="loading"
            @click="fetchRows"
          />
        </div>
      </div>
    </div>

    <q-table
      title="Mevcut Maliyeti Olan Urunler"
      class="ol-table npc-table"
      flat
      bordered
      dense
      virtual-scroll
      :virtual-scroll-item-size="34"
      table-style="max-height: calc(100vh - 190px)"
      separator="cell"
      row-key="__rowKey"
      :rows="rows"
      :columns="columns"
      :loading="loading"
      no-data-label="Kayit bulunamadi"
      :rows-per-page-options="[0]"
      v-model:pagination="tablePagination"
      hide-bottom
    >
      <template #header-cell="props">
        <q-th :props="props">
          <div class="npc-header-cell">
            <div class="npc-head-wrap-3">{{ props.col.label }}</div>
            <q-btn
              v-if="props.col.name !== 'open'"
              dense
              flat
              round
              size="sm"
              icon="filter_alt"
              :color="isColumnFilterActive(props.col.name) ? 'primary' : 'grey-6'"
            >
              <q-menu class="npc-filter-menu" fit>
                <div class="npc-filter-menu-content">
                  <div class="text-caption text-weight-bold q-mb-sm">{{ props.col.label }}</div>
                  <q-input
                    v-model="getColumnFilter(props.col.name).text"
                    dense
                    outlined
                    clearable
                    label="Icerir"
                  />
                  <q-select
                    v-model="getColumnFilter(props.col.name).selected"
                    class="q-mt-sm"
                    dense
                    outlined
                    multiple
                    use-chips
                    use-input
                    emit-value
                    map-options
                    :options="columnDistinctOptions[props.col.name] || []"
                    label="Deger Sec"
                  />
                  <div class="row justify-end q-gutter-sm q-mt-sm">
                    <q-btn dense flat color="grey-7" label="Temizle" @click="clearColumnFilter(props.col.name)" />
                  </div>
                </div>
              </q-menu>
            </q-btn>
          </div>
        </q-th>
      </template>

      <template #body-cell="props">
        <q-td v-if="props.col.name === 'open'" :props="props" class="text-center">
          <q-btn
            icon="open_in_new"
            color="primary"
            flat
            round
            dense
            @click="openRow(props.row)"
          >
            <q-tooltip>Ac</q-tooltip>
          </q-btn>
        </q-td>
        <q-td v-else :props="props" class="npc-wrap-col">
          <div class="npc-wrap-3" :title="String(props.value || '')">{{ props.value }}</div>
        </q-td>
      </template>
    </q-table>

    <q-banner v-if="error" class="bg-red text-white q-mt-sm">
      Hata: {{ error }}
    </q-banner>
  </q-page>

  <q-page v-else class="q-pa-md flex flex-center">
    <div class="text-negative text-subtitle1">
      Bu module erisim yetkiniz yok.
    </div>
  </q-page>
</template>

<script setup>
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { usePermission } from 'src/composables/usePermission'
import { get, extractApiErrorDetail } from 'src/services/api'

const { canRead } = usePermission()
const canReadOrder = canRead('order')
const router = useRouter()

const loading = ref(false)
const error = ref('')
const allRows = ref([])
const tablePagination = ref({
  sortBy: 'Tarihi',
  descending: true,
  page: 1,
  rowsPerPage: 0
})

const filters = reactive({
  search: ''
})
const dateColumns = new Set(['Tarihi', 'dteKayitTarihi', 'dteGuncellemeTarihi', 'SonSiparisTarihi'])

const columns = [
  { name: 'open', label: '', field: 'open', align: 'center', sortable: false, style: 'width:3%', headerStyle: 'width:3%' },
  { name: 'UretimSekli', label: 'Uretim Sekli', field: 'UretimSekli', align: 'left', sortable: true, style: 'width:9%', headerStyle: 'width:9%' },
  { name: 'nOnMLNo', label: 'nOnMLNo', field: 'nOnMLNo', align: 'left', sortable: true, style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'UrunKodu', label: 'UrunKodu', field: 'UrunKodu', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'UrunAdi', label: 'UrunAdi', field: 'UrunAdi', align: 'left', sortable: true, style: 'width:8%', headerStyle: 'width:8%' },
  { name: 'Tarihi', label: 'Tarihi', field: 'Tarihi', align: 'center', sortable: true, format: val => formatDateTR(val), style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'dteKayitTarihi', label: 'dteKayitTarihi', field: 'dteKayitTarihi', align: 'center', sortable: true, format: val => formatDateTR(val), style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'sKullaniciAdi', label: 'sKullaniciAdi', field: 'sKullaniciAdi', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'lTutarTL', label: 'lTutarTL', field: 'lTutarTL', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'lTutarUSD', label: 'lTutarUSD', field: 'lTutarUSD', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'lTutarEURO', label: 'lTutarEURO', field: 'lTutarEURO', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'dteGuncellemeTarihi', label: 'dteGuncellemeTarihi', field: 'dteGuncellemeTarihi', align: 'center', sortable: true, format: val => formatDateTR(val), style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'sGuncellemeKullaniciAdi', label: 'sGuncellemeKullaniciAdi', field: 'sGuncellemeKullaniciAdi', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'nUrtReceteID', label: 'nUrtReceteID', field: 'nUrtReceteID', align: 'left', sortable: true, style: 'width:6%', headerStyle: 'width:6%' },
  { name: 'sAciklama', label: 'sAciklama', field: 'sAciklama', align: 'left', sortable: true, style: 'width:8%', headerStyle: 'width:8%' },
  { name: 'SonSiparisTarihi', label: 'SonSiparisTarihi', field: 'SonSiparisTarihi', align: 'center', sortable: true, format: val => formatDateTR(val), style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'MaliyetDurumu', label: 'MaliyetDurumu', field: 'MaliyetDurumu', align: 'left', sortable: true, style: 'width:8%', headerStyle: 'width:8%' }
]

const columnFilters = reactive({})
const LIST_STATE_STORAGE_KEY = 'bssapp:production-product-costing:has-cost-list-state:v1'

function persistListState () {
  try {
    sessionStorage.setItem(LIST_STATE_STORAGE_KEY, JSON.stringify({
      filters: { search: String(filters.search || '') },
      columnFilters: JSON.parse(JSON.stringify(columnFilters)),
      pagination: { ...tablePagination.value }
    }))
  } catch {}
}

function restoreListState () {
  try {
    const raw = sessionStorage.getItem(LIST_STATE_STORAGE_KEY)
    if (!raw) return
    const saved = JSON.parse(raw)
    filters.search = String(saved?.filters?.search || '')
    Object.assign(columnFilters, saved?.columnFilters && typeof saved.columnFilters === 'object' ? saved.columnFilters : {})
    if (saved?.pagination && typeof saved.pagination === 'object') {
      tablePagination.value = { ...tablePagination.value, ...saved.pagination }
    }
  } catch {}
}

function getColumnFilter (name) {
  if (!columnFilters[name]) {
    columnFilters[name] = {
      text: '',
      selected: []
    }
  }
  return columnFilters[name]
}

function formatDateTR (value) {
  const s = String(value || '').trim()
  if (!s) return ''
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(s)
  if (!m) return s
  return `${m[3]}.${m[2]}.${m[1]}`
}

function formatMoney (value) {
  return Number(value || 0).toLocaleString('tr-TR', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  })
}

const columnDistinctOptions = computed(() => {
  const optionsByColumn = {}

  for (const col of columns) {
    if (col.name === 'open') continue
    const set = new Set()

    for (const row of allRows.value) {
      const val = getColumnComparableValue(row, col.name)
      if (val) set.add(val)
    }

    optionsByColumn[col.name] = Array.from(set)
      .sort((a, b) => a.localeCompare(b, 'tr'))
      .map(v => ({ label: v, value: v }))
  }

  return optionsByColumn
})

const rows = computed(() => {
  let result = allRows.value

  for (const col of columns) {
    if (col.name === 'open') continue

    const cf = getColumnFilter(col.name)
    const text = String(cf.text || '').trim().toLowerCase()
    const selected = Array.isArray(cf.selected) ? cf.selected : []

    if (!text && selected.length === 0) continue

    result = result.filter((row) => {
      const value = getColumnComparableValue(row, col.name)
      const valueLC = value.toLowerCase()

      if (text && !valueLC.includes(text)) return false
      if (selected.length > 0 && !selected.includes(value)) return false
      return true
    })
  }

  return result
})

function getColumnComparableValue (row, colName) {
  if (row?.__cmp?.[colName] !== undefined) return row.__cmp[colName]
  if (dateColumns.has(colName)) return formatDateTR(row?.[colName])
  return String(row?.[colName] ?? '').trim()
}

function buildComparableMap (row) {
  const cmp = {}
  for (const col of columns) {
    if (col.name === 'open') continue
    cmp[col.name] = dateColumns.has(col.name)
      ? formatDateTR(row?.[col.name])
      : String(row?.[col.name] ?? '').trim()
  }
  return cmp
}

function isColumnFilterActive (name) {
  const cf = getColumnFilter(name)
  return !!String(cf.text || '').trim() || (Array.isArray(cf.selected) && cf.selected.length > 0)
}

function clearColumnFilter (name) {
  const cf = getColumnFilter(name)
  cf.text = ''
  cf.selected = []
}

function clearAllColumnFilters () {
  for (const col of columns) {
    if (col.name === 'open') continue
    clearColumnFilter(col.name)
  }
}

let searchTimer = null
let filterWatchEnabled = false
watch(
  () => filters.search,
  () => {
    if (!filterWatchEnabled) return
    clearTimeout(searchTimer)
    searchTimer = setTimeout(() => {
      fetchRows()
    }, 400)
  }
)

async function fetchRows () {
  loading.value = true
  error.value = ''
  try {
    const data = await get('/pricing/production-product-costing/has-cost-products', {
      search: filters.search || '',
      offset: 0,
      limit: 300
    })

    const list = Array.isArray(data) ? data : []
    const sortedList = list.slice().sort((a, b) => {
      const aDate = Date.parse(String(a?.Tarihi || ''))
      const bDate = Date.parse(String(b?.Tarihi || ''))
      const aTs = Number.isNaN(aDate) ? 0 : aDate
      const bTs = Number.isNaN(bDate) ? 0 : bDate
      return bTs - aTs
    })

    allRows.value = sortedList.map((x, i) => ({
      __rowKey: `${x?.nOnMLNo || ''}-${x?.UrunKodu || ''}-${i}`,
      __cmp: buildComparableMap(x),
      ...x
    }))

    tablePagination.value = {
      ...tablePagination.value,
      sortBy: 'Tarihi',
      descending: true,
      page: 1
    }
  } catch (err) {
    error.value = await extractApiErrorDetail(err)
    allRows.value = []
  } finally {
    loading.value = false
  }
}

function clearFilters () {
  filters.search = ''
  clearAllColumnFilters()
  fetchRows()
}

function openRow (row) {
  const urunKodu = String(row?.UrunKodu || '').trim()
  if (!urunKodu) return

  persistListState()

  router.push({
    name: 'production-product-costing-has-cost-history',
    query: { urun_kodu: urunKodu }
  })
}

onMounted(async () => {
  if (!canReadOrder.value) return
  restoreListState()
  await nextTick()
  filterWatchEnabled = true
  await fetchRows()
})
</script>

<style scoped>
.npc-page {
  padding: 10px;
}

.npc-filter-bar {
  margin-bottom: 8px;
}

.npc-filter-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 10px;
  align-items: center;
}

.npc-filter-input {
  min-width: 118px;
  width: 136px;
  flex: 0 0 136px;
}

.npc-search {
  min-width: 240px;
  max-width: 420px;
  flex: 1 1 360px;
}

.npc-filter-actions {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  flex: 0 0 auto;
}

.npc-filter-menu {
  min-width: 300px;
}

.npc-filter-menu-content {
  padding: 10px;
}

.npc-table :deep(.q-table thead th) {
  font-size: 11px;
  padding: 3px 4px;
  white-space: normal !important;
  vertical-align: top !important;
  line-height: 1.15;
}

.npc-table :deep(.q-table tbody td) {
  font-size: 11px;
  padding: 2px 4px;
  white-space: normal !important;
  vertical-align: top !important;
  line-height: 1.15;
}

.npc-table :deep(.q-table) {
  width: 100%;
  table-layout: fixed;
}

.npc-wrap-col {
  white-space: normal !important;
}

.npc-header-cell {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 4px;
  width: 100%;
}

.npc-head-wrap-3 {
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  line-height: 1.15;
  white-space: normal;
  word-break: break-word;
}

.npc-wrap-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  line-height: 1.15;
  white-space: normal;
  word-break: break-word;
}

@media (max-width: 1440px) {
  .npc-filter-row {
    flex-wrap: wrap;
    align-items: flex-start;
  }

  .npc-filter-actions {
    flex-wrap: wrap;
  }

  .npc-filter-input {
    flex: 1 1 140px;
  }
}
</style>
