<template>
  <q-page
    class="order-page product-series-page q-pa-md"
    :style="{
      '--grid-header-h': showGridHeader ? `${schemaRows.length * 28}px` : '0px',
      '--beden-count': 16
    }"
  >
    <div class="sticky-stack">
      <div class="save-toolbar row items-center q-gutter-sm">
        <div>
          <div class="text-subtitle2 text-weight-bold">B2B'de Olmayan Stoklu Varyantlar</div>
          <div class="text-caption text-grey-8">
            Stogu olan ancak B2B tarafinda urun/renk/dim3 kombosu bulunmayan varyantlar listelenir. Bu ekrandan kaydetme yapilmaz.
          </div>
        </div>
        <q-space />
        <q-btn color="primary" outline icon="grid_on" label="Excel" :disable="!displayRows.length" @click="exportVisibleExcel" />
        <q-btn color="secondary" outline icon="refresh" label="Yenile" :loading="loading" @click="reload" />
      </div>

      <div v-if="showGridHeader" class="order-grid-header series-grid-header">
        <div class="col-fixed model">
          <div class="filter-head">
            <span>MODEL</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('model') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('model')" floating color="primary">{{ activeFilterCount('model') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.model" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('model')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('model')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.model"
                    :options="filteredFilterOptions('model')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed desc-col">
          <div class="filter-head">
            <span>DESC</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('desc') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('desc')" floating color="primary">{{ activeFilterCount('desc') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.desc" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('desc')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('desc')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.desc"
                    :options="filteredFilterOptions('desc')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed kategori">
          <div class="filter-head">
            <span>KATEGORI</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('kategori') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('kategori')" floating color="primary">{{ activeFilterCount('kategori') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.kategori" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('kategori')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('kategori')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.kategori"
                    :options="filteredFilterOptions('kategori')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed renk">
          <div class="filter-head">
            <span>RENK</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('renk') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('renk')" floating color="primary">{{ activeFilterCount('renk') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.renk" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('renk')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('renk')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.renk"
                    :options="filteredFilterOptions('renk')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed ana">
          <div class="filter-head">
            <span>URUN ANA GRUBU</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('ana') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('ana')" floating color="primary">{{ activeFilterCount('ana') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.ana" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('ana')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('ana')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.ana"
                    :options="filteredFilterOptions('ana')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed alt">
          <div class="filter-head">
            <span>URUN ALT GRUBU</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('alt') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('alt')" floating color="primary">{{ activeFilterCount('alt') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.alt" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('alt')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('alt')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.alt"
                    :options="filteredFilterOptions('alt')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>
        <div class="col-fixed marka">
          <div class="filter-head">
            <span>MARKA</span>
            <q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('marka') ? 'primary' : 'grey-8'">
              <q-badge v-if="activeFilterCount('marka')" floating color="primary">{{ activeFilterCount('marka') }}</q-badge>
              <q-menu class="column-filter-menu" anchor="bottom left" self="top left">
                <div class="q-pa-sm">
                  <q-input v-model="filterSearch.marka" dense outlined clearable placeholder="Ara" autofocus />
                  <div class="row q-gutter-xs q-mt-sm">
                    <q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('marka')" />
                    <q-btn dense flat size="sm" label="Temizle" @click="clearFilter('marka')" />
                  </div>
                  <q-separator class="q-my-sm" />
                  <q-option-group
                    v-model="columnFilters.marka"
                    :options="filteredFilterOptions('marka')"
                    type="checkbox"
                    dense
                    class="column-filter-options"
                  />
                </div>
              </q-menu>
            </q-btn>
          </div>
        </div>

        <div class="beden-block">
          <div
            v-for="grp in schemaRows"
            :key="'series-hdr-' + grp.key"
            class="grp-row"
          >
            <div class="grp-title">{{ grp.title }}</div>
            <div class="grp-body">
              <div v-for="v in paddedSchemaValues(grp)" :key="'hdr-' + grp.key + '-' + v.key" class="grp-cell hdr" :class="{ ghost: v.ghost }">
                {{ v.ghost ? '' : v.value }}
              </div>
            </div>
          </div>
        </div>

        <div class="total-header-cell">TOPLAM</div>
        <div class="series-header-cell">SERI</div>
      </div>
    </div>

    <q-banner v-if="errorMessage" class="bg-red-1 text-negative q-my-sm rounded-borders" dense>
      {{ errorMessage }}
    </q-banner>

    <q-banner v-else-if="!loading && !displayRows.length" class="bg-blue-1 text-primary q-my-sm rounded-borders" dense>
      B2B'de olmayan stoklu varyant bulunamadi.
    </q-banner>

    <q-inner-loading :showing="loading">
      <q-spinner color="primary" size="42px" />
    </q-inner-loading>

    <div class="order-scroll-y series-scroll">
      <div v-if="displayRows.length" class="order-grid-body series-grid-body">
        <div
          v-for="row in displayRows"
          :key="row.row_key"
          class="series-flat-row warning"
        >
          <div class="sub-col model">{{ row.product_code || '-' }}</div>
          <div class="sub-col desc">{{ row.product_description || '-' }}</div>
          <div class="sub-col kategori">{{ row.kategori || '-' }}</div>
          <div class="sub-col renk">
            <div class="renk-kodu">{{ variantCode(row) }}</div>
            <div class="renk-aciklama">{{ row.color_title || '-' }}</div>
          </div>
          <div class="sub-col ana">{{ row.urun_ana_grubu || '-' }}</div>
          <div class="sub-col alt">{{ row.urun_alt_grubu || '-' }}</div>
          <div class="sub-col marka">{{ row.marka || '-' }}</div>

          <div class="flat-size-cells">
            <div v-for="sz in rowSizeCells(row)" :key="`${row.row_key}-${sz.key}`" class="beden-cell" :class="{ ghost: sz.ghost }">
              {{ formatQty(row._mapped_size_qty?.[sz.value]) }}
            </div>
          </div>

          <div class="total-cell">{{ formatQty(row.total_qty) }}</div>

          <div class="series-select-cell" @click.stop>
            <q-select
              v-model="row._series_ids"
              dense
              outlined
              multiple
              emit-value
              map-options
              use-chips
              :options="seriesOptions"
              option-value="id"
              option-label="label"
              disable
            />
            <div class="series-meta">
              <q-badge color="grey-7">Salt okunur</q-badge>
              <span v-if="row.mapping_warning" class="mapping-warning">{{ row.mapping_warning }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </q-page>
</template>

<script setup>
import { computed, onMounted, ref } from 'vue'
import { Notify } from 'quasar'
import api from 'src/services/api'
import {
  detectBedenGroup,
  normalizeBedenLabel,
  schemaByKey as fallbackSchemaByKey,
  useOrderEntryStore
} from 'src/stores/orderentryStore'

const orderStore = useOrderEntryStore()

const loading = ref(false)
const rows = ref([])
const definitions = ref([])
const errorMessage = ref('')
const columnFilters = ref({
  model: [],
  desc: [],
  kategori: [],
  renk: [],
  ana: [],
  alt: [],
  marka: []
})
const filterSearch = ref({
  model: '',
  desc: '',
  kategori: '',
  renk: '',
  ana: '',
  alt: '',
  marka: ''
})

const showGridHeader = computed(() => !loading.value && productGroups.value.length > 0)

const seriesOptions = computed(() => definitions.value.map(item => ({
  ...item,
  label: formatSeries(item)
})))

const displayRows = computed(() => {
  const list = rows.value.filter(rowPassesFilters)
  const productTotals = productTotalQtyMap(list)
  return list.sort((a, b) => {
    const groupDiff = Number(productTotals.get(b.product_code) || 0) - Number(productTotals.get(a.product_code) || 0)
    if (groupDiff !== 0) return groupDiff
    const code = String(a.product_code || '').localeCompare(String(b.product_code || ''), 'tr')
    if (code !== 0) return code
    const color = String(a.color_code || '').localeCompare(String(b.color_code || ''), 'tr')
    if (color !== 0) return color
    const dim3 = String(a.dim3_code || '').localeCompare(String(b.dim3_code || ''), 'tr')
    if (dim3 !== 0) return dim3
    return Number(b.total_qty || 0) - Number(a.total_qty || 0)
  })
})

function productTotalQtyMap (list) {
  const totals = new Map()
  for (const row of list || []) {
    const code = String(row?.product_code || '').trim()
    if (!code) continue
    totals.set(code, Number(totals.get(code) || 0) + Number(row?.total_qty || 0))
  }
  return totals
}

const productGroups = computed(() => displayRows.value)

const filterOptions = computed(() => ({
  model: uniqueOptions(rows.value.map(row => row.product_code)),
  desc: uniqueOptions(rows.value.map(row => row.product_description)),
  kategori: uniqueOptions(rows.value.map(row => row.kategori)),
  renk: uniqueOptions(rows.value.map(row => variantCode(row))),
  ana: uniqueOptions(rows.value.map(row => row.urun_ana_grubu)),
  alt: uniqueOptions(rows.value.map(row => row.urun_alt_grubu)),
  marka: uniqueOptions(rows.value.map(row => row.marka))
}))

const schemaRows = computed(() => {
  const map = getSchemaMap()
  const preferred = ['tak', 'ayk', 'ayk_garson', 'yas', 'pan', 'gom', 'aksbir']
  const ordered = preferred
    .map(key => map?.[key])
    .filter(Boolean)
  const extras = Object.values(map || {})
    .filter(grp => grp?.key && !preferred.includes(grp.key))
  return [...ordered, ...extras]
})

function uniqueOptions (values) {
  return [...new Set(values.map(v => String(v || '').trim()).filter(Boolean))]
    .sort((a, b) => a.localeCompare(b, 'tr'))
    .map(value => ({ label: value, value }))
}

function filteredFilterOptions (key) {
  const needle = normalizeFilterText(filterSearch.value[key])
  const opts = filterOptions.value[key] || []
  if (!needle) return opts
  return opts.filter(opt => normalizeFilterText(opt.label).includes(needle))
}

function activeFilterCount (key) {
  return Array.isArray(columnFilters.value[key]) ? columnFilters.value[key].length : 0
}

function selectAllFilter (key) {
  columnFilters.value[key] = filteredFilterOptions(key).map(opt => opt.value)
}

function clearFilter (key) {
  columnFilters.value[key] = []
}

function rowPassesFilters (row) {
  return filterMatch('model', row.product_code) &&
    filterMatch('desc', row.product_description) &&
    filterMatch('kategori', row.kategori) &&
    filterMatch('renk', variantCode(row)) &&
    filterMatch('ana', row.urun_ana_grubu) &&
    filterMatch('alt', row.urun_alt_grubu) &&
    filterMatch('marka', row.marka)
}

function filterMatch (key, value) {
  const selected = columnFilters.value[key] || []
  if (!selected.length) return true
  return selected.includes(String(value || '').trim())
}

function normalizeFilterText (value) {
  return String(value || '')
    .trim()
    .toLocaleLowerCase('tr-TR')
}

function normalizeRow (row) {
  const ids = Array.isArray(row.series_ids) ? row.series_ids.map(Number).filter(Boolean) : []
  const mappedInfo = mapRowSizesToSchema(row)
  return {
    ...row,
    series_ids: ids,
    _series_ids: [...ids],
    _grp_key: mappedInfo.grpKey,
    _schema: mappedInfo.schema,
    _mapped_size_qty: mappedInfo.mapped
  }
}

async function reload () {
  loading.value = true
  errorMessage.value = ''
  try {
    if (!orderStore.schemaMap || !Object.keys(orderStore.schemaMap).length) {
      orderStore.initSchemaMap()
    }
    await orderStore.ensureProductSizeMatchRules()
    const res = await api.get('/pricing/product-series/mappings/orphans', { timeout: 180000 })
    rows.value = (res.data?.rows || []).map(normalizeRow)
    definitions.value = res.data?.definitions || []
  } catch (err) {
    errorMessage.value = err?.response?.data || err?.message || 'B2B olmayan stoklu varyantlar alinamadi'
    Notify.create({ type: 'negative', message: errorMessage.value })
  } finally {
    loading.value = false
  }
}

function paddedSchemaValues (grp) {
  const values = Array.isArray(grp?.values) ? grp.values.map(v => normalizeBedenLabel(v)) : []
  const out = values.slice(0, 16).map((value, index) => ({ key: `${value}-${index}`, value, ghost: false, toString: () => value }))
  while (out.length < 16) {
    const index = out.length
    out.push({ key: `ghost-${index}`, value: `__ghost_${index}`, ghost: true, toString: () => '' })
  }
  return out
}

function rowSizeCells (row) {
  const schema = row?._schema || getSchemaMap()?.[row?._grp_key] || fallbackSchemaByKey.tak
  return paddedSchemaValues(schema)
}

function getSchemaMap () {
  return Object.keys(orderStore.schemaMap || {}).length
    ? orderStore.schemaMap
    : fallbackSchemaByKey
}

function normalizedSchemaLabelMap (schema) {
  const out = new Map()
  for (const label of schema?.values || []) {
    const normalized = normalizeBedenLabel(label)
    if (!out.has(normalized)) out.set(normalized, label)
  }
  return out
}

function detectRowGroupKey (row, rawSizeLabels) {
  const fallback = detectRowGroupKeyFallback(row, rawSizeLabels)
  if (fallback) return fallback
  return detectBedenGroup(
    rawSizeLabels,
    row.urun_ana_grubu || '',
    row.kategori || '',
    row.kategori || '',
    row.urun_alt_grubu || ''
  )
}

function normalizeMatchText (value) {
  return String(value || '')
    .trim()
    .toLocaleUpperCase('tr-TR')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
}

function detectRowGroupKeyFallback (row, rawSizeLabels) {
  const ana = normalizeMatchText(row?.urun_ana_grubu)
  const alt = normalizeMatchText(row?.urun_alt_grubu)
  const marka = normalizeMatchText(row?.marka)
  const text = `${ana} ${alt} ${marka}`
  const sizes = (rawSizeLabels || []).map(v => normalizeBedenLabel(v))
  const hasLetterSize = sizes.some(v => ['XS', 'S', 'M', 'L', 'XL', '2XL', '3XL', '4XL', '5XL', '6XL', '7XL'].includes(v))

  if (['KRAVAT', 'PAPYON', 'KEMER', 'CORAP', 'FULAR', 'MENDIL', 'KASKOL', 'ASKI', 'AKSESUAR'].some(key => text.includes(key))) return 'aksbir'
  if (text.includes('AYAKKABI')) return text.includes('GARSON') ? 'ayk_garson' : 'ayk'
  if (text.includes('PANTOLON')) return 'pan'
  if (text.includes('GOMLEK') || hasLetterSize) return 'gom'
  if (text.includes('TAKIM') || text.includes('DAMATLIK') || text.includes('CEKET') || text.includes('KABAN') || text.includes('MONT') || text.includes('YELEK')) return 'tak'

  return ''
}

function mapRowSizesToSchema (row) {
  const sizeEntries = Object.entries(row?.size_qty || {})
  const rawSizeLabels = sizeEntries.map(([rawSize]) => normalizeBedenLabel(rawSize))
  const schemaMap = getSchemaMap()
  const grpKey = detectRowGroupKey(row, rawSizeLabels)
  const schema = pickSchemaForRow(schemaMap, grpKey, rawSizeLabels)
  const schemaLabelMap = normalizedSchemaLabelMap(schema)
  const mapped = {}

  for (const [rawSize, rawQty] of sizeEntries) {
    const normalized = normalizeBedenLabel(rawSize)
    const target = normalizeBedenLabel(schemaLabelMap.get(normalized) || normalized)
    mapped[target] = Number(mapped[target] || 0) + Number(rawQty || 0)
  }

  if (grpKey === 'aksbir' && !Object.keys(mapped).length && Number(row?.total_qty || 0) > 0) {
    mapped[' '] = Number(row.total_qty || 0)
  }

  if (grpKey !== 'aksbir' && Object.keys(mapped).some(k => String(k).trim() !== '')) {
    delete mapped[' ']
  }

  return { grpKey, schema, mapped }
}

function pickSchemaForRow (schemaMap, grpKey, rawSizeLabels) {
  const primary = grpKey && schemaMap?.[grpKey] ? schemaMap[grpKey] : null
  const rawSet = new Set((rawSizeLabels || []).map(v => normalizeBedenLabel(v)).filter(Boolean))
  if (!rawSet.size) return primary
  const primarySet = new Set((primary?.values || []).map(v => normalizeBedenLabel(v)))
  if ([...rawSet].some(v => primarySet.has(v))) return primary

  let best = primary
  let bestScore = 0
  for (const schema of Object.values(schemaMap || {})) {
    const schemaSet = new Set((schema?.values || []).map(v => normalizeBedenLabel(v)))
    const score = [...rawSet].reduce((sum, v) => sum + (schemaSet.has(v) ? 1 : 0), 0)
    if (score > bestScore) {
      best = schema
      bestScore = score
    }
  }
  return best
}

function formatQty (value) {
  const n = Number(value || 0)
  if (!Number.isFinite(n) || n === 0) return ''
  return n.toLocaleString('tr-TR', { maximumFractionDigits: 2 })
}

function formatSeries (item) {
  const code = String(item?.code || '').trim()
  const title = String(item?.title || '').trim()
  return title ? `${code}/${title}` : code
}

function variantCode (row) {
  const c = String(row?.color_code || '').trim()
  const d = String(row?.dim3_code || '').trim()
  return d ? `${c}-${d}` : (c || '-')
}

function exportFileStamp () {
  const now = new Date()
  const pad = v => String(v).padStart(2, '0')
  return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}`
}

function csvEscape (v) {
  const s = String(v ?? '')
  if (!s.includes(',') && !s.includes('"') && !s.includes('\n')) return s
  return `"${s.replace(/"/g, '""')}"`
}

function exportVisibleExcel () {
  const cols = ['MODEL', 'DESC', 'KATEGORI', 'RENK', 'URUN ANA GRUBU', 'URUN ALT GRUBU', 'MARKA']
  const sizeCols = schemaRows.value.flatMap(grp => paddedSchemaValues(grp).map(v => (v.ghost ? '' : v.value))).filter(Boolean)
  cols.push(...sizeCols)
  cols.push('TOPLAM', 'SERI', 'UYARI')

  const lines = [cols.map(csvEscape).join(',')]
  for (const row of displayRows.value) {
    const sizeValues = []
    const cells = rowSizeCells(row)
    for (const cell of cells) {
      sizeValues.push(cell.ghost ? '' : formatQty(row._mapped_size_qty?.[cell.value]))
    }
    lines.push([
      row.product_code || '',
      row.product_description || '',
      row.kategori || '',
      variantCode(row),
      row.urun_ana_grubu || '',
      row.urun_alt_grubu || '',
      row.marka || '',
      ...sizeValues,
      formatQty(row.total_qty),
      '',
      row.mapping_warning || ''
    ].map(csvEscape).join(','))
  }

  const blob = new Blob([lines.join('\n')], { type: 'text/csv;charset=utf-8;' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `b2b-olmayan-stoklu-varyantlar_${exportFileStamp()}.csv`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

onMounted(() => reload())
</script>

<style scoped>
.product-series-page {
  --filter-h: 0px;
  --psq-sticky-offset: 12px;
  --grp-title-w: 90px;
  --col-desc: var(--col-aciklama);
  --col-kategori-series: 86px;
  --col-marka-series: var(--col-marka, 90px);
  --psq-header-h: var(--grid-header-h);
  --series-total-w: 76px;
  --series-col-w: minmax(220px, 1fr);
  background: #f5f1da;
}

.series-scroll {
  overflow: auto;
}

.series-grid-header,
.series-flat-row {
  grid-template-columns:
    var(--col-model)
    var(--col-desc)
    var(--col-kategori-series)
    var(--col-renk)
    var(--col-ana)
    var(--col-alt)
    var(--col-marka-series)
    calc(var(--grp-title-w) + var(--grp-title-gap) + (var(--beden-w) * var(--beden-count)))
    var(--series-total-w)
    var(--series-col-w) !important;
  width: 100%;
  min-width: min-content;
}

.series-grid-header {
  top: calc(var(--header-h) + var(--filter-h) + var(--save-h) + var(--psq-sticky-offset)) !important;
}

.series-grid-header .col-fixed,
.total-header-cell,
.series-header-cell {
  writing-mode: horizontal-tb !important;
  transform: none !important;
  height: var(--psq-header-h) !important;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px !important;
  line-height: 1 !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 4px !important;
}

.filter-head {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  min-width: 0;
}

.filter-head span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.column-filter-menu {
  width: 280px;
  max-width: 86vw;
}

.column-filter-options {
  max-height: 300px;
  overflow: auto;
}

.series-grid-header .beden-block {
  height: var(--psq-header-h) !important;
}

.series-grid-header .grp-row {
  height: var(--beden-h) !important;
  align-items: center;
}

.series-grid-header .grp-title {
  width: var(--grp-title-w) !important;
  text-align: center !important;
  padding-right: 0 !important;
  font-size: 10px !important;
}

.series-grid-header .grp-cell.hdr {
  height: var(--beden-h) !important;
  font-size: 10px !important;
}

.series-grid-header .grp-cell.hdr.ghost {
  color: transparent;
}

.total-header-cell,
.series-header-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff8d1;
  border-left: 1px solid #d4c79f;
  font-weight: 700;
}

.total-header-cell {
  grid-column: 9 / 10;
}

.series-header-cell {
  grid-column: 10 / 11;
}

.series-flat-row {
  display: grid;
  min-height: 72px;
  align-items: center;
  background: #fff9c4 !important;
  border-top: 1px solid #d4c79f !important;
  border-bottom: 1px solid #d4c79f !important;
}

.series-flat-row.dirty {
  background: #fff0cf !important;
}

.series-flat-row.warning {
  box-shadow: inset 3px 0 0 #f59e0b;
}

.series-flat-row .sub-col {
  display: flex;
  align-items: center;
  padding: 0 8px;
  font-size: 12px;
  font-weight: 500;
  color: #111;
  min-width: 0;
  border-right: 1px solid #d4c79f;
  white-space: normal;
  overflow: visible;
  line-height: 1.2;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.series-flat-row .sub-col.model { grid-column: 1; }
.series-flat-row .sub-col.desc { grid-column: 2; }
.series-flat-row .sub-col.kategori { grid-column: 3; }
.series-flat-row .sub-col.renk { grid-column: 4; }
.series-flat-row .sub-col.ana { grid-column: 5; }
.series-flat-row .sub-col.alt { grid-column: 6; }
.series-flat-row .sub-col.marka { grid-column: 7; }

.series-flat-row .sub-col.model,
.series-flat-row .sub-col.kategori,
.series-flat-row .sub-col.renk,
.series-flat-row .sub-col.ana,
.series-flat-row .sub-col.alt,
.series-flat-row .sub-col.marka {
  justify-content: center;
  text-align: center;
}

.series-flat-row .sub-col.desc {
  justify-content: flex-start;
  text-align: left;
}

.series-flat-row .sub-col.renk {
  flex-direction: column;
  gap: 2px;
  line-height: 1.1;
}

.series-flat-row .sub-col.renk .renk-kodu {
  font-weight: 700;
}

.series-flat-row .sub-col.renk .renk-aciklama {
  font-size: 11px;
  opacity: 0.9;
}

.flat-size-cells {
  grid-column: 8;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--beden-w);
  justify-content: start;
  align-items: stretch;
  width: calc(var(--grp-title-w) + var(--grp-title-gap) + (var(--beden-w) * var(--beden-count)));
  padding-left: calc(var(--grp-title-w) + var(--grp-title-gap));
  margin-left: 0;
  height: 100%;
  box-sizing: border-box;
}

.flat-size-cells::before,
.flat-size-cells::after {
  content: none;
}

.flat-size-cells .beden-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--beden-w);
  height: 100%;
  box-sizing: border-box;
  border: 1px solid #d4c79f;
  border-right: none;
  background: #fffef6;
  color: #1f1f1f;
  font-size: 13px;
  font-weight: 700;
}

.flat-size-cells .beden-cell:last-child {
  border-right: 1px solid #d4c79f;
}

.flat-size-cells .beden-cell.ghost {
  color: transparent;
}

.total-cell {
  grid-column: 9;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 10px;
  border-left: 1px solid #d4c79f;
  border-right: 1px solid #d4c79f;
  color: var(--q-primary, #1976d2);
  font-size: 14px;
  font-weight: 800;
}

.series-select-cell {
  grid-column: 10 / 11;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  border-left: 1px solid #d4c79f;
  background: #fffdf0;
}

.series-select-cell :deep(.q-field__control) {
  min-height: 36px;
}

.series-chip {
  max-width: 170px;
  font-size: 11px;
}

.series-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 18px;
  font-size: 11px;
}

.mapping-warning {
  color: #b45309;
}
</style>
