<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import api from '@/utils/api';
import LoadingState from '~/components/shared/LoadingState.vue';
import PermissionRow from '~/components/apps/setting/permission/PermissionRow.vue';
import { useSnackbarStore } from '~/store/snackbar';
import type { RoleAccessItem, RoleAccessPermission } from '~/types/setting/rolePermission';

const route = useRoute();
const router = useRouter();
const snackbarStore = useSnackbarStore();
const access = ref<RoleAccessItem[]>([]);

const roleId = computed(() => {
  const roleId = route.params.roleId;
  return roleId
});

const roleName = ref<string>('');
  
const loading = ref(false);

type ApiRoleAccessPermission = Partial<RoleAccessPermission> & { id?: number | null };

const normalizePermission = (permission?: ApiRoleAccessPermission): RoleAccessPermission => {
  return {
    id: permission?.id ?? null,
    create: Boolean(permission?.create),
    read: Boolean(permission?.read),
    update: Boolean(permission?.update),
    delete: Boolean(permission?.delete),
    disable: Boolean(permission?.disable),
  };
};

const indexRoleItemsById = (items: any[], map = new Map<number, any>()) => {
  for (const item of items ?? []) {
    if (typeof item?.id === 'number') map.set(item.id, item);
    if (Array.isArray(item?.children) && item.children.length) indexRoleItemsById(item.children, map);
  }
  return map;
};

const mergeRolePermissionsIntoAll = (allItems: any[], roleMap: Map<number, any>): RoleAccessItem[] => {
  return (allItems ?? []).map((allItem: any) => {
    const roleItem = roleMap.get(allItem?.id);
    const children = Array.isArray(allItem?.children)
      ? mergeRolePermissionsIntoAll(allItem.children, roleMap)
      : undefined;

    return {
      ...allItem,
      permission: normalizePermission(roleItem?.permission),
      ...(children ? { children } : {}),
    } as RoleAccessItem;
  });
};

const fetchRolePermissions = async () => {
  if (!roleId.value) return;

  loading.value = true;
  try {
    const [roleResponse, mergedResponse] = await Promise.all([
      api.get<any>(`/api/v1/roles/master/${roleId.value}`),
      api.get<any>(`/api/v1/roles/permissions/rolemaster/${roleId.value}`),
    ]);

    roleName.value = roleResponse.data?.data?.name ?? '';

    const payload = mergedResponse.data?.data?.[0];
    const dataRole = payload?.dataRole ?? [];
    const dataAll = payload?.dataAll ?? [];
    const roleMap = indexRoleItemsById(dataRole);
    access.value = mergeRolePermissionsIntoAll(dataAll, roleMap);

  } catch (error: any) {
    const message = error?.response?.data?.message || error?.message || 'Gagal memuat data permission role';
    snackbarStore.showSnackbar(message, 'error');
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  fetchRolePermissions();
});

definePageMeta({
  middleware: 'auth',
});
</script>

<template>
  <v-card elevation="0" class="mb-5">
    <v-card-title class="pa-4">
      <div class="d-flex align-center">
        <v-btn icon size="small" variant="text" class="me-2" @click="router.push('/apps/setting/permission')">
          <v-icon>mdi-arrow-left</v-icon>
        </v-btn>
        <div>
          <h4 class="text-h4">Role : {{ roleName }}</h4>
        </div>
      </div>
    </v-card-title>
  </v-card>

  <LoadingState :loading="loading" :empty="access.length === 0 && !loading" loading-text="Memuat permission..." empty-text="Data Kosong">
    <v-card elevation="2">
      <v-card-text class="pa-5">
        <div class="d-flex align-center py-3 px-5 header-row">
          <div class="flex-grow-1 text-subtitle-2 font-weight-semibold">MODUL &amp; FITUR</div>
          <div class="perm-header">LIHAT</div>
          <div class="perm-header">TAMBAH</div>
          <div class="perm-header">UBAH</div>
          <div class="perm-header">HAPUS</div>
        </div>
        <v-divider />

        <PermissionRow v-for="item in access" :key="item.id" :item="item" :level="0"  />
      </v-card-text>
    </v-card>
  </LoadingState>
</template>

<style scoped>
.perm-header {
  width: 84px;
  text-align: center;
  font-weight: 600;
}
</style>
