<script setup lang="ts">
import { Check, ChevronRight, LockKeyhole, Minus, Save } from '@lucide/vue'
import { computed, ref, watch } from 'vue'

import type { AdminTeamPermission, AdminTeamRole } from '../../types/awards'
import Button from '../ui/Button.vue'
import Modal from '../ui/Modal.vue'

interface PermissionGroup {
  label: string
  items: AdminTeamPermission[]
}

const props = defineProps<{
  open: boolean
  saving: boolean
  hasRoleChanges: boolean
  roles: AdminTeamRole[]
  permissions: AdminTeamPermission[]
  permissionGroups: PermissionGroup[]
  roleHasPermission: (roleKey: string, permissionKey: string) => boolean
  setRolePermission: (roleKey: string, permissionKey: string, checked: boolean) => void
  saveRolePermissions: () => void | Promise<void>
}>()

const emit = defineEmits<{
  close: []
}>()

const selectedRoleKey = ref<string | null>(null)

const selectedRole = computed(() =>
  props.roles.find((role) => role.key === selectedRoleKey.value) ?? props.roles[0] ?? null,
)

const selectedPermissionGroups = computed(() => {
  if (!selectedRole.value) return []
  return props.permissionGroups.map((group) => ({
    ...group,
    grantedCount: group.items.filter((permission) => props.roleHasPermission(selectedRole.value!.key, permission.key)).length,
  }))
})

watch(
  () => [props.open, props.roles.map((role) => role.key).join('|')] as const,
  ([open]) => {
    if (!open) return
    if (!selectedRoleKey.value || !props.roles.some((role) => role.key === selectedRoleKey.value)) {
      selectedRoleKey.value = props.roles[0]?.key ?? null
    }
  },
  { immediate: true },
)

function rolePermissionLocked(roleKey: string) {
  return roleKey === 'owner' || roleKey === 'creator'
}

function rolePermissionCount(roleKey: string) {
  return props.permissions.filter((permission) => props.roleHasPermission(roleKey, permission.key)).length
}

function permissionModeLabel(permission: AdminTeamPermission) {
  return permission.readOnlySupported ? 'Lesen oder Schreiben' : 'Schreiben'
}

async function save() {
  await props.saveRolePermissions()
}
</script>

<template>
  <Modal
    :open="open"
    title="Rollenrechte"
    subtitle="Rolle im Navigator wählen und Berechtigungen im Detail pflegen."
    size="xl"
    @close="emit('close')"
  >
    <div class="grid gap-5 xl:grid-cols-[280px_minmax(0,1fr)]">
      <aside class="space-y-3">
        <div class="rounded-[24px] border border-violet-100 bg-violet-50/55 p-4">
          <p class="text-[10px] font-bold uppercase tracking-[0.18em] text-violet-500">Navigator</p>
          <p class="mt-2 text-sm leading-6 text-slate-600">
            Jede Rolle zeigt ihre Rechte einzeln. Das ist kompakter als die alte Matrix und passt zum aktuellen Admin-Workspace.
          </p>
        </div>

        <button
          v-for="role in roles"
          :key="role.key"
          type="button"
          class="w-full rounded-[24px] border p-4 text-left transition"
          :class="selectedRole?.key === role.key
            ? 'border-violet-200 bg-gradient-to-br from-violet-50 via-white to-[#fff4e6] shadow-[0_18px_40px_rgba(139,108,219,0.14)]'
            : 'border-violet-100 bg-white/90 hover:border-violet-200 hover:bg-violet-50/50'"
          @click="selectedRoleKey = role.key"
        >
          <div class="flex items-start justify-between gap-3">
            <div class="min-w-0">
              <p class="text-[11px] font-bold uppercase tracking-[0.16em] text-violet-500">{{ role.label }}</p>
              <p class="mt-2 text-sm leading-6 text-slate-600">{{ role.description }}</p>
            </div>
            <span
              class="grid h-9 w-9 shrink-0 place-items-center rounded-2xl border transition"
              :class="selectedRole?.key === role.key ? 'border-violet-200 bg-white text-violet-700' : 'border-violet-100 bg-violet-50 text-violet-500'"
            >
              <LockKeyhole v-if="rolePermissionLocked(role.key)" class="h-4 w-4" />
              <ChevronRight v-else class="h-4 w-4" />
            </span>
          </div>
          <div class="mt-3 flex flex-wrap items-center gap-2">
            <span class="rounded-full border border-violet-100 bg-white px-2.5 py-1 text-[10px] font-bold uppercase tracking-[0.12em] text-violet-700">
              {{ rolePermissionCount(role.key) }}/{{ permissions.length }} Rechte
            </span>
            <span
              v-if="rolePermissionLocked(role.key)"
              class="rounded-full border border-slate-200 bg-slate-50 px-2.5 py-1 text-[10px] font-bold uppercase tracking-[0.12em] text-slate-500"
            >
              fixiert
            </span>
          </div>
        </button>
      </aside>

      <section v-if="selectedRole" class="space-y-4">
        <div class="rounded-[28px] border border-violet-100 bg-white/95 p-5 shadow-[0_18px_40px_rgba(124,92,255,0.08)]">
          <div class="flex flex-wrap items-start justify-between gap-4">
            <div class="min-w-0">
              <p class="text-[10px] font-bold uppercase tracking-[0.18em] text-violet-500">Rolle</p>
              <h3 class="mt-1 text-2xl font-bold text-slate-950">{{ selectedRole.label }}</h3>
              <p class="mt-2 max-w-3xl text-sm leading-6 text-slate-600">{{ selectedRole.description }}</p>
            </div>
            <div class="flex flex-wrap gap-2">
              <span class="rounded-full border border-violet-100 bg-violet-50 px-3 py-1 text-xs font-bold text-violet-700">
                {{ rolePermissionCount(selectedRole.key) }}/{{ permissions.length }} Rechte aktiv
              </span>
              <span
                v-if="rolePermissionLocked(selectedRole.key)"
                class="rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-bold text-slate-500"
              >
                Systemrolle
              </span>
            </div>
          </div>

          <div
            v-if="rolePermissionLocked(selectedRole.key)"
            class="mt-4 flex items-start gap-3 rounded-[22px] border border-slate-200 bg-slate-50/80 px-4 py-3 text-sm text-slate-600"
          >
            <LockKeyhole class="mt-0.5 h-4 w-4 shrink-0 text-slate-400" />
            <p>Owner und Creator bleiben auf Vollzugriff fixiert und können hier nur eingesehen werden.</p>
          </div>
        </div>

        <div
          v-for="group in selectedPermissionGroups"
          :key="group.label"
          class="rounded-[28px] border border-violet-100 bg-white/92 p-5 shadow-[0_14px_34px_rgba(124,92,255,0.06)]"
        >
          <div class="flex flex-wrap items-start justify-between gap-3 border-b border-violet-100 pb-4">
            <div>
              <p class="text-[10px] font-bold uppercase tracking-[0.18em] text-violet-500">Bereich</p>
              <h4 class="mt-1 text-lg font-bold text-slate-950">{{ group.label }}</h4>
            </div>
            <span class="rounded-full border border-violet-100 bg-violet-50 px-3 py-1 text-xs font-bold text-violet-700">
              {{ group.grantedCount }}/{{ group.items.length }} aktiv
            </span>
          </div>

          <div class="mt-4 grid gap-3">
            <div
              v-for="permission in group.items"
              :key="permission.key"
              class="grid gap-3 rounded-[24px] border border-violet-100 bg-violet-50/35 p-4 md:grid-cols-[minmax(0,1fr)_auto] md:items-center"
            >
              <div class="min-w-0">
                <div class="flex flex-wrap items-center gap-2">
                  <p class="text-base font-bold text-slate-950">{{ permission.label }}</p>
                  <span class="rounded-full border border-violet-100 bg-white px-2.5 py-1 text-[10px] font-bold uppercase tracking-[0.12em] text-violet-700">
                    {{ permissionModeLabel(permission) }}
                  </span>
                  <span class="rounded-full border border-slate-200 bg-white px-2.5 py-1 text-[10px] font-bold text-slate-500">
                    {{ permission.menuPath }}
                  </span>
                </div>
                <p class="mt-2 text-sm leading-6 text-slate-600">{{ permission.description }}</p>
              </div>

              <button
                type="button"
                class="inline-flex items-center justify-center gap-2 rounded-2xl border px-4 py-3 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400 focus-visible:ring-offset-2 disabled:cursor-not-allowed"
                :class="[
                  roleHasPermission(selectedRole.key, permission.key)
                    ? rolePermissionLocked(selectedRole.key)
                      ? 'border-slate-200 bg-slate-100 text-slate-500'
                      : 'border-violet-500 bg-violet-600 text-white shadow-lg shadow-violet-500/20 hover:bg-violet-500'
                    : rolePermissionLocked(selectedRole.key)
                      ? 'border-slate-200 bg-slate-50 text-slate-300'
                      : 'border-violet-200 bg-white text-violet-700 hover:bg-violet-50',
                ]"
                :disabled="rolePermissionLocked(selectedRole.key)"
                :aria-label="`${selectedRole.label}: ${permission.label}`"
                :aria-pressed="roleHasPermission(selectedRole.key, permission.key)"
                @click="setRolePermission(selectedRole.key, permission.key, !roleHasPermission(selectedRole.key, permission.key))"
              >
                <Check v-if="roleHasPermission(selectedRole.key, permission.key)" class="h-4 w-4" :stroke-width="3" />
                <Minus v-else class="h-4 w-4" :stroke-width="3" />
                {{ roleHasPermission(selectedRole.key, permission.key) ? 'Aktiv' : 'Aus' }}
              </button>
            </div>
          </div>
        </div>
      </section>
    </div>

    <template #footer>
      <Button type="button" variant="ghost" @click="emit('close')">Schließen</Button>
      <Button type="button" :disabled="saving || !hasRoleChanges" @click="save">
        <Save class="mr-2 h-4 w-4" />
        {{ saving ? 'Speichert...' : 'Speichern' }}
      </Button>
    </template>
  </Modal>
</template>
