<template>
  <q-dialog
    ref="dialogRef"
    full-height
    @hide="onDialogHide"
  >
    <q-card
      class="column no-wrap"
      style="width: 100%; max-width: 95vw; height: 100%"
    >
      <DefaultDialogHeader
        :title="`Permissões: ${group.label}`"
        @close="onDialogCancel"
      />

      <q-card-section
        class="col column no-wrap q-pa-none"
        style="min-height: 0"
      >
        <div
          class="row items-stretch col no-wrap"
          style="min-height: 0"
        >
          <div
            class="col-12 col-md-6 column no-wrap"
            style="min-height: 0"
          >
            <div class="text-center text-subtitle1 text-weight-medium q-pa-sm">
              Menu
            </div>

            <q-separator />

            <q-inner-loading :showing="loading" />

            <q-list
              v-if="!loading"
              class="col scroll"
              separator
            >
              <q-item
                v-for="item in menus"
                :key="item.scope"
                :active="selectedScope === item.scope"
                active-class="bg-orange-1 text-secondary"
                clickable
                @click="selectedScope = item.scope"
              >
                <q-item-section avatar>
                  <q-icon
                    color="dark"
                    :name="item.icon"
                  />
                </q-item-section>

                <q-item-section>
                  <q-item-label>
                    {{ item.label }}
                  </q-item-label>

                  <q-item-label caption>
                    <PermissionLevelBadges
                      :bits="bitsFor(item.scope)"
                    />
                  </q-item-label>
                </q-item-section>

                <q-item-section side>
                  <q-btn
                    color="dark"
                    dense
                    flat
                    icon="mdi-pencil-outline"
                    round
                    @click.stop
                  >
                    <q-tooltip>
                      Editar permissões
                    </q-tooltip>

                    <PermissionLevelMenu
                      :available-bits="availableBitsFor(item.scope)"
                      :bits="bitsFor(item.scope)"
                      @update:bits="
                        (value) => setBits(item.scope, value)
                      "
                    />
                  </q-btn>
                </q-item-section>
              </q-item>
            </q-list>
          </div>

          <q-separator vertical />

          <div
            class="col column no-wrap"
            style="min-height: 0"
          >
            <div class="text-center text-subtitle1 text-weight-medium q-pa-sm">
              Detalhes
            </div>

            <q-separator />

            <div
              v-if="!selected"
              class="col column flex-center text-center text-grey-7 q-pa-md"
            >
              <div>
                Nenhum menu selecionado!
              </div>

              <div class="text-caption">
                ← Selecione um menu à esquerda para visualizar suas permissões.
              </div>
            </div>

            <q-list
              v-else
              class="col scroll"
              separator
            >
              <q-item>
                <q-item-section avatar>
                  <q-icon
                    color="dark"
                    :name="selected.icon"
                  />
                </q-item-section>

                <q-item-section>
                  <q-item-label>
                    {{ selected.label }}
                  </q-item-label>

                  <q-item-label caption>
                    <PermissionLevelBadges
                      :bits="bitsFor(selected.scope)"
                    />
                  </q-item-label>
                </q-item-section>

                <q-item-section side>
                  <q-btn
                    color="dark"
                    dense
                    flat
                    icon="mdi-pencil-outline"
                    round
                  >
                    <PermissionLevelMenu
                      :available-bits="availableBitsFor(selected.scope)"
                      :bits="bitsFor(selected.scope)"
                      @update:bits="
                        (value) => setBits(selected.scope, value)
                      "
                    />
                  </q-btn>
                </q-item-section>
              </q-item>
            </q-list>
          </div>
        </div>
      </q-card-section>

      <q-card-actions
        align="right"
        class="q-pa-md"
      >
        <q-btn
          color="primary"
          label="Cancelar"
          no-caps
          outline
          @click="onDialogCancel"
        />

        <q-btn
          color="secondary"
          label="Salvar"
          no-caps
          :disable="loading"
          :loading="saving"
          @click="onSave"
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup>
import {
  applyComputedLevels,
  FRANCHISEE_PERMISSION_MENUS,
} from "../permission_menus";

import { computed, onMounted, ref } from "vue";

import {
  getUserTypePermissions,
  updateUserTypePermissions,
} from "src/api/user_type";

import { Notify, useDialogPluginComponent } from "quasar";

import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import PermissionLevelBadges from "./PermissionLevelBadges.vue";
import PermissionLevelMenu from "./PermissionLevelMenu.vue";

defineEmits([...useDialogPluginComponent.emits]);

const { group } = defineProps({
  group: {
    type: Object,
    required: true,
  },
});

const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  useDialogPluginComponent();

const availableBitsByScope = ref({});
const bitsByScope = ref({});
const loading = ref(false);
const permissionIdByScope = ref({});
const saving = ref(false);
const selectedScope = ref(null);

const menus = computed(() =>
  FRANCHISEE_PERMISSION_MENUS.filter(
    (menu) =>
      permissionIdByScope.value[menu.scope] !== undefined,
  ),
);

const selected = computed(
  () =>
    menus.value.find(
      (menu) => menu.scope === selectedScope.value,
    ) ?? null,
);

const availableBitsFor = (scope) =>
  availableBitsByScope.value[scope] ?? 0;

const bitsFor = (scope) =>
  bitsByScope.value[scope] ?? 0;

const fetchPermissions = async () => {
  loading.value = true;

  try {
    const payload = await getUserTypePermissions(group.id);

    const permissionsByScope = Object.fromEntries(
      payload.permissions.map((permission) => [
        permission.scope,
        permission,
      ]),
    );

    for (const menu of FRANCHISEE_PERMISSION_MENUS) {
      const permission = permissionsByScope[menu.scope];

      if (!permission) continue;

      availableBitsByScope.value[menu.scope] =
        permission.available_bits;

      bitsByScope.value[menu.scope] =
        applyComputedLevels(permission.bits);

      permissionIdByScope.value[menu.scope] =
        permission.id;
    }
  } catch {
    Notify.create({
      message:
        "Não foi possível carregar as permissões do grupo.",
      type: "negative",
    });
  } finally {
    loading.value = false;
  }
};

const onSave = async () => {
  saving.value = true;

  try {
    const permissions = Object.entries(
      permissionIdByScope.value,
    ).map(([scope, id]) => ({
      bits: bitsByScope.value[scope] ?? 0,
      permission_id: id,
    }));

    await updateUserTypePermissions(
      group.id,
      permissions,
    );

    Notify.create({
      message: "Permissões atualizadas.",
      type: "positive",
    });

    onDialogOK();
  } catch {
    Notify.create({
      message:
        "Não foi possível salvar as permissões.",
      type: "negative",
    });
  } finally {
    saving.value = false;
  }
};

const setBits = (scope, value) => {
  bitsByScope.value[scope] = value;
};

onMounted(fetchPermissions);
</script>
