<script lang="ts" setup>
import { Link, useForm } from '@inertiajs/vue3'
import { computed } from 'vue'
import AdminLayout from '@/Layouts/AdminLayout.vue'

interface RoleData {
  id: number
  name: string
  is_protected: boolean
  permissions: string[]
}

interface Props {
  role: RoleData
  permissionGroups: Record<string, string[]>
  usersCount: number
}

defineOptions({ layout: AdminLayout })

const props = defineProps<Props>()

const form = useForm({
  name: props.role.name,
  permissions: [...props.role.permissions],
})

function formatGroupName(name: string): string {
  return name.replace(/_/g, ' ').replace(/\b\w/g, (c: string) => c.toUpperCase())
}

function formatPermissionAction(permission: string): string {
  const parts = permission.split('.')
  return parts.length > 1 ? parts[1].replace(/_/g, ' ') : permission
}

function isGroupFullySelected(group: string): boolean {
  const perms = props.permissionGroups[group] ?? []
  return perms.length > 0 && perms.every((p: string) => form.permissions.includes(p))
}

function isGroupPartiallySelected(group: string): boolean {
  const perms = props.permissionGroups[group] ?? []
  const selectedCount = perms.filter((p: string) => form.permissions.includes(p)).length
  return selectedCount > 0 && selectedCount < perms.length
}

function toggleGroup(group: string): void {
  const perms = props.permissionGroups[group] ?? []
  if (isGroupFullySelected(group)) {
    form.permissions = form.permissions.filter((p: string) => !perms.includes(p))
  }
  else {
    const newPerms = perms.filter((p: string) => !form.permissions.includes(p))
    form.permissions.push(...newPerms)
  }
}

function togglePermission(permission: string): void {
  const index = form.permissions.indexOf(permission)
  if (index >= 0) {
    form.permissions.splice(index, 1)
  }
  else {
    form.permissions.push(permission)
  }
}

function selectAll(): void {
  form.permissions = Object.values(props.permissionGroups).flat()
}

function deselectAll(): void {
  form.permissions = []
}

const totalPermissions = computed<number>(() => Object.values(props.permissionGroups).flat().length)

const groupNames = computed<string[]>(() => Object.keys(props.permissionGroups).filter((g: string) => g !== 'legacy'))
const hasLegacy = computed<boolean>(() => 'legacy' in props.permissionGroups)

function submit(): void {
  form.put(`/staff/roles/${props.role.id}`, {
    preserveScroll: true,
  })
}
</script>

<template>
  <div>
    <!-- Header -->
    <div class="d-flex align-center justify-space-between mb-6">
      <div>
        <div class="d-flex align-center gap-2 mb-1">
          <Link href="/staff/roles" class="text-decoration-none">
            <VBtn icon="tabler-arrow-left" variant="text" size="small" />
          </Link>
          <span class="text-h4 font-weight-bold">Edit Role</span>
        </div>
        <div class="text-body-2 text-medium-emphasis ms-10">
          Update permissions for "{{ role.name }}"
        </div>
      </div>
    </div>

    <form @submit.prevent="submit">
      <VRow>
        <!-- Role Details -->
        <VCol cols="12" lg="8">
          <VCard title="Role Details" class="mb-6">
            <VCardText>
              <VTextField
                v-model="form.name"
                label="Role Name"
                placeholder="e.g. billing_admin"
                hint="Lowercase, letters, numbers, and underscores only"
                persistent-hint
                :error-messages="form.errors.name"
                :disabled="role.is_protected"
              />
              <VAlert
                v-if="role.is_protected"
                type="info"
                variant="tonal"
                density="compact"
                class="mt-3"
              >
                This is a built-in role. Its name cannot be changed.
              </VAlert>
            </VCardText>
          </VCard>

          <!-- Permissions -->
          <VCard class="mb-6">
            <VCardTitle class="d-flex align-center justify-space-between">
              <span>Permissions</span>
              <div class="d-flex ga-2">
                <VBtn
                  variant="text"
                  size="small"
                  color="primary"
                  @click="selectAll"
                >
                  Select All
                </VBtn>
                <VBtn
                  variant="text"
                  size="small"
                  @click="deselectAll"
                >
                  Clear All
                </VBtn>
              </div>
            </VCardTitle>
            <VCardText>
              <div v-if="form.errors.permissions" class="mb-4">
                <VAlert type="error" variant="tonal" density="compact">
                  {{ form.errors.permissions }}
                </VAlert>
              </div>

              <VRow>
                <VCol
                  v-for="group in groupNames"
                  :key="group"
                  cols="12"
                  md="6"
                  lg="4"
                >
                  <VCard variant="outlined" class="h-100">
                    <VCardTitle class="text-body-1 font-weight-bold pa-3 pb-1">
                      <VCheckbox
                        :model-value="isGroupFullySelected(group)"
                        :indeterminate="isGroupPartiallySelected(group)"
                        :label="formatGroupName(group)"
                        density="compact"
                        hide-details
                        @change="toggleGroup(group)"
                      />
                    </VCardTitle>
                    <VCardText class="pt-0 pb-3">
                      <div
                        v-for="perm in permissionGroups[group]"
                        :key="perm"
                        class="ms-6"
                      >
                        <VCheckbox
                          :model-value="form.permissions.includes(perm)"
                          :label="formatPermissionAction(perm)"
                          density="compact"
                          hide-details
                          class="text-capitalize"
                          @change="togglePermission(perm)"
                        />
                      </div>
                    </VCardText>
                  </VCard>
                </VCol>
              </VRow>

              <!-- Legacy permissions (if any) -->
              <div v-if="hasLegacy" class="mt-6">
                <div class="text-body-2 font-weight-bold mb-2">
                  Legacy Permissions
                </div>
                <div class="d-flex flex-wrap ga-2">
                  <VCheckbox
                    v-for="perm in permissionGroups['legacy']"
                    :key="perm"
                    :model-value="form.permissions.includes(perm)"
                    :label="perm"
                    density="compact"
                    hide-details
                    @change="togglePermission(perm)"
                  />
                </div>
              </div>
            </VCardText>
          </VCard>
        </VCol>

        <!-- Sidebar -->
        <VCol cols="12" lg="4">
          <VCard title="Role Info" class="mb-6">
            <VCardText>
              <div class="d-flex justify-space-between align-center mb-3">
                <span class="text-body-2 text-medium-emphasis">Selected Permissions</span>
                <VChip size="small" variant="tonal" color="primary">
                  {{ form.permissions.length }} / {{ totalPermissions }}
                </VChip>
              </div>
              <div class="d-flex justify-space-between align-center mb-3">
                <span class="text-body-2 text-medium-emphasis">Assigned Users</span>
                <VChip size="small" variant="tonal" color="info">
                  {{ usersCount }}
                </VChip>
              </div>
              <div v-if="role.is_protected" class="d-flex justify-space-between align-center">
                <span class="text-body-2 text-medium-emphasis">Type</span>
                <VChip size="small" variant="outlined" color="warning">
                  Built-in
                </VChip>
              </div>
            </VCardText>
          </VCard>

          <!-- Actions -->
          <VCard>
            <VCardText>
              <VBtn
                type="submit"
                color="primary"
                block
                :loading="form.processing"
                :disabled="form.processing"
                prepend-icon="tabler-check"
                class="mb-3"
              >
                Update Role
              </VBtn>
              <Link href="/staff/roles" class="text-decoration-none">
                <VBtn
                  variant="outlined"
                  block
                >
                  Cancel
                </VBtn>
              </Link>
            </VCardText>
          </VCard>
        </VCol>
      </VRow>
    </form>
  </div>
</template>
