<template>
  <div v-if="canUpdateUser && !lookupsLoaded" class="q-pa-xl flex flex-center">

    <q-spinner
      color="primary"
      size="48px"
    />

  </div>

  <q-page v-if="canUpdateUser" class="permissions-page">

    <!-- ================= STICKY STACK ================= -->
    <div class="sticky-stack">

      <!-- FILTER BAR -->
      <div
        v-if="lookupsLoaded"
        class="filter-bar row q-col-gutter-md"
      >


      <div class="col-4">
        <q-select
          v-model="roleId"
          :options="roles"
          option-value="id"
          option-label="title"
          emit-value
          map-options
          label="Rol"
          dense
          outlined
          @update:model-value="loadMatrix"
        />





      </div>

        <div class="col-4">
          <q-select
            v-model="deptCode"
            :options="departments"
            option-value="id"
            option-label="title"
            emit-value
            map-options
            label="Departman"
            dense
            outlined
            @update:model-value="loadMatrix"
          />




        </div>

      </div>

      <!-- SAVE TOOLBAR -->
      <div class="save-toolbar">

        <div class="label">
          Rol + Departman Yetkilendirme
        </div>

        <q-btn
          flat
          icon="list"
          label="Liste"
          @click="goList"
        />

        <q-btn
          v-if="canUpdateUser"
          color="primary"
          icon="save"
          label="Kaydet"
          :disable="!dirty"
          @click="save"
        />

      </div>

      <div
        v-if="lookupsLoaded && roleId && deptCode"
        class="group-members-toolbar"
      >
        <div class="group-members-toolbar__members">
          <div class="text-caption text-weight-bold">
            Grup Kullanicilari ({{ members.length }})
          </div>
          <div v-if="membersLoading" class="q-ml-sm">
            <q-spinner color="primary" size="18px" />
          </div>
          <div v-else-if="members.length" class="group-members-toolbar__chips">
            <q-chip
              v-for="member in members"
              :key="member.id"
              dense
              square
              color="blue-1"
              text-color="primary"
            >
              {{ member.id }} - {{ member.full_name || member.username }}
              <q-tooltip>{{ member.username }}</q-tooltip>
            </q-chip>
          </div>
          <div v-else class="text-caption text-grey-7 q-ml-sm">
            Bu grupta aktif kullanici bulunmuyor.
          </div>
        </div>

        <div class="group-members-toolbar__add">
          <q-select
            v-model="memberUserId"
            :options="filteredUserOptions"
            option-value="id"
            option-label="title"
            emit-value
            map-options
            dense
            outlined
            clearable
            use-input
            input-debounce="150"
            label="Kullanici ekle"
            class="group-members-toolbar__select"
            @filter="filterUsers"
          />
          <q-btn
            color="primary"
            icon="person_add"
            label="Ekle"
            :disable="!memberUserId || addingMember"
            :loading="addingMember"
            @click="addMember"
          />
        </div>
      </div>

    </div>


    <!-- ================= TABLE SCROLL ================= -->

    <div
      v-if="lookupsLoaded"
      class="permissions-table-scroll"
    >


    <q-table
        class="permissions-table"
        :rows="rows"
        :columns="columns"
        row-key="module"
        flat
        bordered
        dense
        :loading="loading"

        :rows-per-page-options="[0]"
        :pagination="{ rowsPerPage: 0 }"
      >

        <!-- ========== HEADER ========== -->
        <template v-slot:header-cell="props">

          <q-th :props="props">

            <!-- Module başlığı -->
            <span v-if="props.col.name === 'module'">
              {{ props.col.label }}
            </span>

            <!-- Checkbox kolon başlığı -->
            <div v-else class="column items-center">

              <span class="text-caption">
                {{ props.col.label }}
              </span>

              <q-checkbox
                dense
                :model-value="isColumnChecked(props.col.name)"
                @update:model-value="toggleColumn(props.col.name, $event)"
              />

            </div>

          </q-th>

        </template>


        <!-- ========== BODY ========== -->
        <template v-slot:body-cell="props">

          <q-td
            :props="props"
            :class="props.col.name === 'module'
              ? 'permissions-sticky-col'
              : ''"
          >

            <!-- Module adı -->
            <span v-if="props.col.name === 'module'">
              {{ props.row.label }}
            </span>

            <!-- Checkbox -->
            <q-checkbox
              v-else
              v-model="props.row[props.col.name]"
              dense
              @update:model-value="dirty = true"
            />

          </q-td>

        </template>

      </q-table>

    </div>

  </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, ref, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Notify } from 'quasar'
import api from 'src/services/api'
import { usePermission } from 'src/composables/usePermission'

const { canUpdate } = usePermission()
// This screen manages system-wide permission sets; gate by system:update.
const canUpdateUser = canUpdate('system')
const route = useRoute()
const router = useRouter()


/* ================= STATE ================= */

const roles = ref([])
const departments = ref([])
const users = ref([])
const filteredUserOptions = ref([])
const members = ref([])

const roleId = ref(null)
const deptCode = ref(null)
const memberUserId = ref(null)

const rows = ref([])

const loading = ref(false)
const membersLoading = ref(false)
const addingMember = ref(false)
const dirty = ref(false)
const lookupsLoaded = ref(false)


/* ================= ACTIONS ================= */

const actions = [
  { key: 'write',  label: 'Ekleme' },
  { key: 'read',   label: 'Görüntüleme' },
  { key: 'delete', label: 'Silme' },
  { key: 'update', label: 'Güncelleme' },
  { key: 'export', label: 'Çıktı' }
]


/* ================= MODULES ================= */

const modules = ref([])


/* ================= TABLE ================= */

const columns = [

  {
    name: 'module',
    label: 'Modül',
    field: 'label',
    align: 'left'
  },

  ...actions.map(a => ({
    name: a.key,
    label: a.label,
    align: 'center'
  }))
]

let matrixLoading = false

function goList () {
  router.push({ name: 'role-dept-permissions-list' })
}

function applyRouteSelection () {
  const qRole = String(route.query.roleId || '').trim()
  const qDept = String(route.query.deptCode || '').trim()

  if (/^\d+$/.test(qRole) && Number(qRole) > 0) {
    roleId.value = qRole
  }

  if (qDept) {
    deptCode.value = qDept
  }

  if (roleId.value && deptCode.value) {
    loadMatrix()
  }
}


/* ================= LOOKUPS ================= */

async function loadLookups () {

  const [r, d, m, u] = await Promise.all([
    api.get('/lookups/roles-perm'),
    api.get('/lookups/departments-perm'),
    api.get('/lookups/modules'),
    api.get('/lookups/users-perm')
  ])

  roles.value = r.data || []
  departments.value = d.data || []
  modules.value = m.data || []
  users.value = u.data || []
  filteredUserOptions.value = [...users.value]

  lookupsLoaded.value = true
}


/* ================= INIT MATRIX ================= */

function initMatrix () {

  rows.value = modules.value.map(m => {

    const row = {
      module: String(m.value).toLowerCase().trim(),
      label: m.label
    }

    actions.forEach(a => {
      row[a.key] = false
    })

    return row
  })
}


/* ================= LOAD ================= */

async function loadMatrix () {

  if (!roleId.value || !deptCode.value) {
    members.value = []
    return
  }
  if (matrixLoading) return

  matrixLoading = true
  loading.value = true

  try {

    if (!modules.value.length) {
      await loadLookups()
    }

    initMatrix()

    const [res] = await Promise.all([
      api.get(`/roles/${roleId.value}/departments/${deptCode.value}/permissions`),
      loadMembers()
    ])

    const list = Array.isArray(res.data) ? res.data : []

    console.log('PERM LIST:', list.slice(0, 10))


    // ✅ BACKEND → UI ACTION MAP
    const actionMap = {
      insert: 'write',
      view: 'read',
      delete: 'delete',
      update: 'update',
      export: 'export'
    }


    list.forEach(p => {

      const code = String(p.module_code || p.module)
        .toLowerCase()
        .trim()

      const rawAction = String(p.action)
        .toLowerCase()
        .trim()

      const mappedAction = actionMap[rawAction] || rawAction


      const row = rows.value.find(r => r.module === code)

      if (row && row.hasOwnProperty(mappedAction)) {
        row[mappedAction] = Boolean(p.allowed)
      }
    })


    dirty.value = false

  } catch (err) {

    console.error('PERM LOAD ERROR:', err)

    Notify.create({
      type: 'negative',
      message: 'Yetkiler yüklenemedi'
    })

  } finally {

    loading.value = false
    matrixLoading = false
  }
}

const availableUserOptions = computed(() => {
  const memberIDs = new Set(members.value.map(member => Number(member.id)))
  return users.value.filter(user => !memberIDs.has(Number(user.id)))
})

function filterUsers (value, update) {
  update(() => {
    const needle = String(value || '').trim().toLocaleLowerCase('tr')
    filteredUserOptions.value = needle
      ? availableUserOptions.value.filter(user => String(user.title || '').toLocaleLowerCase('tr').includes(needle))
      : [...availableUserOptions.value]
  })
}

async function loadMembers () {
  if (!roleId.value || !deptCode.value) {
    members.value = []
    return
  }
  membersLoading.value = true
  try {
    const res = await api.get(
      `/roles/${roleId.value}/departments/${encodeURIComponent(deptCode.value)}/members`
    )
    members.value = Array.isArray(res.data) ? res.data : []
    filteredUserOptions.value = [...availableUserOptions.value]
  } catch (err) {
    console.error('GROUP MEMBERS LOAD ERROR:', err)
    members.value = []
    Notify.create({
      type: 'negative',
      message: 'Grup kullanicilari yuklenemedi'
    })
  } finally {
    membersLoading.value = false
  }
}

async function addMember () {
  if (!roleId.value || !deptCode.value || !memberUserId.value) return
  addingMember.value = true
  try {
    const res = await api.post(
      `/roles/${roleId.value}/departments/${encodeURIComponent(deptCode.value)}/members`,
      { user_id: Number(memberUserId.value) }
    )
    members.value = Array.isArray(res.data) ? res.data : []
    memberUserId.value = null
    filteredUserOptions.value = [...availableUserOptions.value]
    Notify.create({
      type: 'positive',
      message: 'Kullanici gruba eklendi'
    })
  } catch (err) {
    console.error('GROUP MEMBER ADD ERROR:', err)
    Notify.create({
      type: 'negative',
      message: 'Kullanici gruba eklenemedi'
    })
  } finally {
    addingMember.value = false
  }
}


/* ================= SAVE ================= */

async function save () {

  try {

    loading.value = true

    const payload = []

    // UI action keys -> backend action codes
    const toBackendAction = {
      write: 'insert',
      read: 'view',
      delete: 'delete',
      update: 'update',
      export: 'export'
    }

    rows.value.forEach(r => {

      actions.forEach(a => {

        payload.push({
          module: r.module,
          action: toBackendAction[a.key] || a.key,
          allowed: r[a.key]
        })
      })
    })


    await api.post(
      `/roles/${roleId.value}/departments/${deptCode.value}/permissions`,
      payload
    )


    Notify.create({
      type: 'positive',
      message: 'Kaydedildi'
    })

    dirty.value = false

  } catch {

    Notify.create({
      type: 'negative',
      message: 'Kayıt hatası'
    })

  } finally {

    loading.value = false
  }
}


/* ================= COLUMN ================= */

function isColumnChecked (key) {

  if (!rows.value.length) return false

  return rows.value.every(r => r[key] === true)
}


function toggleColumn (key, val) {

  rows.value.forEach(r => {
    r[key] = val
  })

  dirty.value = true
}


/* ================= INIT ================= */

onMounted(async () => {
  await loadLookups()
  applyRouteSelection()
})

watch(roleId, v => console.log('ROLE_ID >>>', v))
watch(deptCode, v => console.log('DEPT >>>', v))
watch(
  () => [route.query.roleId, route.query.deptCode],
  () => {
    if (!lookupsLoaded.value) return
    applyRouteSelection()
  }
)

</script>

<style scoped>
.group-members-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  background: #fff;
  border-top: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}

.group-members-toolbar__members {
  min-width: 0;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
}

.group-members-toolbar__chips {
  min-width: 0;
  display: flex;
  gap: 4px;
  overflow-x: auto;
  padding-left: 8px;
}

.group-members-toolbar__add {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.group-members-toolbar__select {
  width: 300px;
}

@media (max-width: 1100px) {
  .group-members-toolbar {
    align-items: stretch;
    flex-direction: column;
  }

  .group-members-toolbar__select {
    width: min(100%, 420px);
  }
}
</style>
