<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 (Model Kodu / Firma / Veren)"
        >
          <template #append>
            <q-icon name="search" />
          </template>
        </q-input>

        <q-input
          v-model="filters.fromDate"
          class="npc-filter-input"
          dense
          filled
          type="date"
          label="Baslangic Tarihi"
        />

        <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 class="npc-missing-count text-caption text-grey-7">
            Maliyeti Girilmemis Satir Sayisi: <b>{{ missingCostRowCount }}</b>
          </div>
        </div>
      </div>
    </div>

    <q-table
      title="Maliyeti Olmayan Urunler"
      class="ol-table npc-table"
      flat
      bordered
      dense
      separator="cell"
      row-key="__rowKey"
      :rows="rows"
      :columns="columns"
      :loading="loading"
      no-data-label="Kayit bulunamadi"
      :rows-per-page-options="[0]"
      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>
                  <template v-if="isNumericColumn(props.col.name)">
                    <div class="row q-col-gutter-sm">
                      <div class="col-6">
                        <q-input
                          v-model="getColumnFilter(props.col.name).min"
                          dense
                          outlined
                          clearable
                          inputmode="decimal"
                          label="Min"
                        />
                      </div>
                      <div class="col-6">
                        <q-input
                          v-model="getColumnFilter(props.col.name).max"
                          dense
                          outlined
                          clearable
                          inputmode="decimal"
                          label="Max"
                        />
                      </div>
                    </div>
                  </template>
                  <template v-else>
                    <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="getColumnDistinctOptions(props.col.name)"
                      label="Deger Sec"
                    />
                  </template>
                  <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">{{ props.value }}</div>
          <q-tooltip v-if="props.value">{{ props.value }}</q-tooltip>
        </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 { useQuasar } from 'quasar'
import { useRouter } from 'vue-router'
import { usePermission } from 'src/composables/usePermission'
import { get, extractApiErrorDetail } from 'src/services/api'
import { createTraceId, slog } from 'src/utils/slog'

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

const loading = ref(false)
const error = ref('')
const allRows = ref([])

const filters = reactive({
  search: '',
  fromDate: '2025-06-01'
})

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,
    classes: 'npc-wrap-col',
    headerClasses: 'npc-wrap-col',
    style: 'width:12%',
    headerStyle: 'width:12%'
  },
  { name: 'nUrtSiparisNo', label: 'Uretim Siparis No', field: 'nUrtSiparisNo', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  {
    name: 'dteIslemTarihi',
    label: 'Islem Tarihi',
    field: 'dteIslemTarihi',
    align: 'center',
    sortable: true,
    format: val => formatDateTR(val),
    style: 'width:7%',
    headerStyle: 'width:7%'
  },
  {
    name: 'FirmaKodu',
    label: 'Firma Kodu',
    field: 'FirmaKodu',
    align: 'left',
    sortable: true,
    classes: 'npc-wrap-col',
    headerClasses: 'npc-wrap-col',
    style: 'width:8%',
    headerStyle: 'width:8%'
  },
  { name: 'FirmaAdi', label: 'Firma Adi', field: 'FirmaAdi', align: 'left', sortable: true, style: 'width:10%', headerStyle: 'width:10%' },
  { name: 'SonIsEmriVeren', label: '2.Firma', field: 'SonIsEmriVeren', align: 'left', sortable: true, style: 'width:9%', headerStyle: 'width:9%' },
  {
    name: 'lMMiktar_G',
    label: 'Miktar (G)',
    field: 'lMMiktar_G',
    align: 'right',
    sortable: true,
    format: val => Number(val || 0).toLocaleString('tr-TR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
    style: 'width:7%',
    headerStyle: 'width:7%'
  },
  {
    name: 'sMModelKodu',
    label: 'Model Kodu',
    field: 'sMModelKodu',
    align: 'left',
    sortable: true,
    classes: 'npc-wrap-col',
    headerClasses: 'npc-wrap-col',
    style: 'width:8%',
    headerStyle: 'width:8%'
  },
  { name: 'sAdi', label: 'Model Adi', field: 'sAdi', align: 'left', sortable: true, style: 'width:9%', headerStyle: 'width:9%' },
  { name: 'sKodu', label: 'Recete Kodu', field: 'sKodu', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'sKullaniciAdi', label: 'Receteyi Acan Kullanici', field: 'sKullaniciAdi', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
  { name: 'sKullaniciAdiGunc', label: 'Receteyi Son Guncelleyen Kullanici', field: 'sKullaniciAdiGunc', align: 'left', sortable: true, style: 'width:6%', headerStyle: 'width:6%' }
]

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

function persistListState () {
  try {
    sessionStorage.setItem(LIST_STATE_STORAGE_KEY, JSON.stringify({
      filters: {
        search: String(filters.search || ''),
        fromDate: String(filters.fromDate || '')
      },
      columnFilters: JSON.parse(JSON.stringify(columnFilters)),
      scrollY: Number(window.scrollY || 0)
    }))
  } catch {}
}

function restoreListState () {
  try {
    const raw = sessionStorage.getItem(LIST_STATE_STORAGE_KEY)
    if (!raw) return 0
    const saved = JSON.parse(raw)
    filters.search = String(saved?.filters?.search || '')
    filters.fromDate = String(saved?.filters?.fromDate || '2025-06-01')
    Object.assign(columnFilters, saved?.columnFilters && typeof saved.columnFilters === 'object' ? saved.columnFilters : {})
    return Number(saved?.scrollY || 0)
  } catch {
    return 0
  }
}

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

function isNumericColumn (name) {
  return name === 'lMMiktar_G'
}

function parseNumberFilter (value) {
  const raw = String(value ?? '').trim()
  if (!raw) return null
  const normalized = raw
    .replace(/\s/g, '')
    .replace(/\./g, '')
    .replace(',', '.')
  const n = Number(normalized)
  return Number.isFinite(n) ? n : null
}

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]}`
}

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 : []
    const min = parseNumberFilter(cf.min)
    const max = parseNumberFilter(cf.max)

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

    result = result.filter((row) => {
      if (isNumericColumn(col.name)) {
        const numericValue = Number(row?.[col.name] || 0)
        if (min !== null && numericValue < min) return false
        if (max !== null && numericValue > max) return false
        return true
      }

      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
})

const missingCostRowCount = computed(() => {
  return Array.isArray(rows.value) ? rows.value.length : 0
})

function getColumnComparableValue (row, colName) {
  if (colName === 'dteIslemTarihi') {
    return formatDateTR(row?.dteIslemTarihi)
  }
  return String(row?.[colName] ?? '').trim()
}

function getColumnDistinctOptions (colName) {
  const set = new Set()
  for (const row of allRows.value) {
    const val = getColumnComparableValue(row, colName)
    if (val) set.add(val)
  }
  return Array.from(set)
    .sort((a, b) => a.localeCompare(b, 'tr'))
    .map(v => ({ label: v, value: v }))
}

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

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

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)
  }
)

watch(
  () => filters.fromDate,
  () => {
    if (!filterWatchEnabled) return
    fetchRows()
  }
)

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

    const list = Array.isArray(data) ? data : []
    allRows.value = list.map((x, i) => ({
      __rowKey: `${x?.sMModelKodu || ''}-${x?.nUrtSiparisNo || 0}-${i}`,
      ...x
    }))
  } catch (err) {
    error.value = await extractApiErrorDetail(err)
    allRows.value = []
  } finally {
    loading.value = false
  }
}

function clearFilters () {
  filters.search = ''
  filters.fromDate = '2025-06-01'
  clearAllColumnFilters()
  fetchRows()
}

function openRow (row) {
  const productCode = String(row?.sMModelKodu || '').trim()
  const recipeCode = String(row?.sKodu || '').trim()
  const traceId = createTraceId('pcd-no-cost')
  if (!productCode || !recipeCode) {
    $q.notify({
      type: 'warning',
      message: 'Detay acmak icin urun ve recete kodu gerekli.',
      position: 'top-right'
    })
    return
  }

  slog.info('production-product-costing.no-cost', 'navigate:detail', {
    trace_id: traceId,
    product_code: productCode,
    recipe_code: recipeCode
  })

  persistListState()

  router.push({
    name: 'production-product-costing-has-cost-detail',
    query: {
      detail_source: 'no-cost',
      urun_kodu: productCode,
      recete_kodu: recipeCode,
      trace_id: traceId
    }
  })
}

onMounted(async () => {
  if (!canReadOrder.value) return
  const savedScrollY = restoreListState()
  await nextTick()
  filterWatchEnabled = true
  await fetchRows()
  if (savedScrollY > 0) {
    await nextTick()
    window.scrollTo({ top: savedScrollY, behavior: 'auto' })
  }
})
</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-missing-count {
  white-space: nowrap;
  align-self: center;
  margin-left: 6px;
}

.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>
