<script setup>
import { computed, ref } from "vue";
import { m, q } from "#imports";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
const { t } = useI18n();
const $q = useQuasar();
const loading = ref(true);
const updating = ref(/* @__PURE__ */ new Set());
const fetchApp = async () => {
  try {
    loading.value = true;
    const { app: app2 } = await q({
      app: {
        permissions: true,
        roles: {
          name: true,
          permissions: true
        }
      }
    });
    return app2;
  } catch (error) {
    $q.notify({
      type: "negative",
      message: t("Failed to load permissions")
    });
    throw error;
  } finally {
    loading.value = false;
  }
};
const app = ref(await fetchApp());
const roles = computed(() => app.value?.roles || []);
const columns = computed(() => [
  {
    label: t("Permission"),
    field: "permission",
    align: "left",
    style: "font-weight: bold; background-color: rgba(0,0,0,0.02);",
    headerStyle: "font-weight: bold;"
  },
  ...roles.value.map((role) => ({
    label: role.name,
    field: role.name,
    align: "center",
    headerStyle: "font-weight: bold;"
  }))
]);
const rows = computed(() => {
  if (!app.value?.permissions) return [];
  return app.value.permissions.map((permission) => {
    const row = { permission };
    roles.value.forEach((role) => {
      row[role.name] = role.permissions.includes(permission);
    });
    return row;
  });
});
const onUpdate = async (value, role, permission) => {
  const updateKey = `${role}-${permission}`;
  updating.value.add(updateKey);
  const roleObj = app.value?.roles.find((r) => r.name === role);
  if (!roleObj) {
    updating.value.delete(updateKey);
    return;
  }
  const originalPermissions = [...roleObj.permissions];
  if (value) {
    if (!roleObj.permissions.includes(permission)) {
      roleObj.permissions = [...roleObj.permissions, permission];
    }
  } else {
    if (roleObj.permissions.includes(permission)) {
      roleObj.permissions = roleObj.permissions.filter((p) => p !== permission);
    }
  }
  try {
    if (value) {
      await m("addPermission", { value: permission, role });
    } else {
      await m("removePermission", { value: permission, role });
    }
    $q.notify({
      type: "positive",
      message: t(value ? "Permission granted successfully" : "Permission removed successfully")
    });
  } catch (error) {
    roleObj.permissions = originalPermissions;
    $q.notify({
      type: "negative",
      message: t("Failed to update permission")
    });
  } finally {
    updating.value.delete(updateKey);
  }
};
const toggleAllForRole = async (role, grant) => {
  const updates = [];
  for (const permission of app.value.permissions) {
    const currentState = role.permissions.includes(permission);
    if (currentState !== grant) {
      updates.push({ permission, role: role.name, grant });
    }
  }
  if (updates.length === 0) return;
  const originalPermissions = [...role.permissions];
  role.permissions = grant ? [...app.value.permissions] : [];
  try {
    for (const update of updates) {
      if (update.grant) {
        await m("addPermission", { value: update.permission, role: update.role });
      } else {
        await m("removePermission", { value: update.permission, role: update.role });
      }
    }
    $q.notify({
      type: "positive",
      message: t(grant ? "All permissions granted" : "All permissions removed")
    });
  } catch (error) {
    role.permissions = originalPermissions;
    $q.notify({
      type: "negative",
      message: t("Failed to update permissions")
    });
  }
};
const filter = ref("");
const selectedRole = ref("");
const filteredRows = computed(() => {
  let filtered = rows.value;
  if (filter.value) {
    filtered = filtered.filter(
      (row) => row.permission.toLowerCase().includes(filter.value.toLowerCase())
    );
  }
  if (selectedRole.value) {
    filtered = filtered.filter((row) => row[selectedRole.value]);
  }
  return filtered;
});
</script>

<template>
  <l-page>

    <!-- 載入指示器 -->
    <div v-if="loading" class="text-center q-pa-md">
      <q-spinner-dots size="50px" />
      <div class="q-mt-sm">{{ $t('Loading permissions...') }}</div>
    </div>

    <!-- 主要內容 -->
    <div v-else>
      <!-- 篩選控制 -->
      <div class="row q-gutter-md q-mb-md">
        <div class="col-md-6 col-12">
          <q-input v-model="filter" :placeholder="$t('Filter permissions')" dense clearable outlined>
            <template v-slot:append>
              <q-icon name="sym_o_search" />
            </template>
          </q-input>
        </div>
        <div class="col-md-6 col-12">
          <q-select v-model="selectedRole"
            :options="[{ label: $t('All Roles'), value: '' }, ...roles.map(r => ({ label: r.name, value: r.name }))]"
            :placeholder="$t('Filter by role')" dense clearable outlined emit-value map-options />
        </div>
      </div>

      <!-- 權限表格 -->
      <q-table :columns="columns" flat bordered :rows="filteredRows" :pagination="{ rowsPerPage: 0 }" dense>

        <template #body="props">
          <q-tr :props="props">
            <q-td :style="columns[0].style" class="text-weight-medium" auto-width>
              <q-icon name="security" class="q-mr-sm text-grey-6" />
              {{ props.row.permission }}
            </q-td>
            <q-td v-for="role in roles" :key="role.name" class="text-center">
              <q-checkbox v-model="props.row[role.name]"
                @update:model-value="onUpdate($event, role.name, props.row.permission)"
                :loading="updating.has(`${role.name}-${props.row.permission}`)"
                :disable="updating.has(`${role.name}-${props.row.permission}`)" />
            </q-td>
          </q-tr>
        </template>

        <template #no-data>
          <div class="full-width text-center q-pa-lg">
            <q-icon name="search_off" size="48px" class="text-grey-5" />
            <div class="text-h6 text-grey-7 q-mt-md">
              {{ $t('No permissions found') }}
            </div>
            <div class="text-body2 text-grey-6">
              {{ $t('Try adjusting your search filters') }}
            </div>
          </div>
        </template>
      </q-table>

      <!-- 結果統計 -->
      <div class="q-mt-md text-caption text-grey-7">
        {{ $t('Showing') }} {{ filteredRows.length }} {{ $t('of') }} {{ rows.length }} {{ $t('permissions') }}
      </div>
    </div>
  </l-page>
</template>
