<script setup lang="ts">
import { computed, watch } from 'vue';
import { useLazyQuery } from '@vue/apollo-composable';

import { Badge } from '@unraid/ui';

import type { AuthAction, PreviewEffectivePermissionsQuery, Role } from '~/composables/gql/graphql';

import { PREVIEW_EFFECTIVE_PERMISSIONS } from '~/components/ApiKey/permissions-preview.query';

interface RawPermission {
  resource: string;
  actions: AuthAction[];
}

interface Props {
  roles?: Role[];
  rawPermissions?: RawPermission[];
  showHeader?: boolean;
  headerText?: string;
}

const props = withDefaults(defineProps<Props>(), {
  roles: () => [],
  rawPermissions: () => [],
  showHeader: true,
  headerText: 'Effective Permissions',
});

// Query for effective permissions
const {
  load: loadEffectivePermissions,
  loading,
  result,
} = useLazyQuery<PreviewEffectivePermissionsQuery>(PREVIEW_EFFECTIVE_PERMISSIONS);

// Computed property for effective permissions from the result
const effectivePermissions = computed(() => {
  return result.value?.previewEffectivePermissions || [];
});

// Format action for display - show the actual enum value or formatted string
const formatAction = (action: string): string => {
  if (action === '*') return 'ALL ACTIONS';

  // If it's already an enum value like CREATE_ANY, READ_ANY, show as-is
  if (action.includes('_')) {
    return action; // Keep the original enum format
  }

  // If it's in scope format like 'create:any' or just 'create', format for display
  if (action.includes(':')) {
    return action.split(':')[0].toUpperCase() + ':' + action.split(':')[1].toUpperCase();
  }

  // For simple verbs, uppercase them
  return action.toUpperCase();
};

// Watch for changes to roles and permissions and reload
watch(
  () => ({
    roles: props.roles,
    rawPermissions: props.rawPermissions,
  }),
  async ({ roles, rawPermissions }) => {
    // Skip if no roles or permissions
    if ((!roles || roles.length === 0) && (!rawPermissions || rawPermissions.length === 0)) {
      return;
    }

    try {
      // Transform permissions to the format expected by the query
      const permissions =
        rawPermissions?.map((perm) => ({
          resource: perm.resource,
          actions: perm.actions,
        })) || [];

      // Call load with the parameters
      await loadEffectivePermissions(null, {
        roles: roles || [],
        permissions: permissions.length > 0 ? permissions : undefined,
      });
    } catch (error) {
      console.error('Failed to load effective permissions:', error);
    }
  },
  { immediate: true, deep: true }
);
</script>

<template>
  <div class="w-full">
    <h3 v-if="showHeader" class="mb-3 flex items-center gap-2 text-sm font-semibold">
      {{ headerText }}
      <span v-if="loading" class="text-muted-foreground text-xs">(loading...)</span>
    </h3>

    <!-- Show effective permissions -->
    <div v-if="effectivePermissions.length > 0 && !loading" class="space-y-2">
      <div class="text-muted-foreground mb-2 text-xs">
        These are the actual permissions that will be granted based on selected roles and custom
        permissions:
      </div>

      <div class="max-h-64 space-y-2 overflow-y-auto">
        <div
          v-for="perm in effectivePermissions"
          :key="perm.resource"
          class="bg-background border-muted rounded border p-2 text-xs"
        >
          <div class="mb-1 flex items-center gap-2">
            <span class="font-medium">{{ perm.resource }}</span>
          </div>
          <div class="flex flex-wrap gap-1">
            <Badge v-for="action in perm.actions" :key="action" variant="green" size="xs">
              {{ formatAction(action) }}
            </Badge>
          </div>
        </div>
      </div>
    </div>

    <!-- Show loading state -->
    <div v-else-if="loading" class="text-muted-foreground text-xs">Loading permissions...</div>

    <!-- Show message when no permissions selected -->
    <div v-else class="text-muted-foreground text-xs italic">No permissions selected yet</div>
  </div>
</template>
