<template>
  <v-card width="100%">
    <v-toolbar>
      <v-row no-gutters class="fill-height px-6" align="center">
        <span class="font-weight-bold text-h5">Create Role</span>
        <v-spacer />
        <v-btn icon density="comfortable" @click="cancel">
          <v-icon>mdi-close</v-icon>
        </v-btn>
      </v-row>
    </v-toolbar>

    <v-card-text style="max-height: 75vh; overflow-y: auto">
      <v-form v-model="validForm" :disabled="disable">
        <v-row no-gutters>
          <v-col cols="12" class="mt-2">
            <v-row no-gutters>
              <InputLabel title="Role Name" required />
              <v-col cols="12">
                <v-text-field
                  v-model="name"
                  density="comfortable"
                  :rules="[requiredRule]"
                />
              </v-col>
            </v-row>
          </v-col>

          <v-col v-if="props.siteState" cols="12" class="mt-2">
            <v-row no-gutters>
              <InputLabel title="Site" />
              <v-col cols="12">
                <v-text-field :model-value="siteName" density="comfortable" readonly disabled :loading="loadSite" />
              </v-col>
            </v-row>
          </v-col>

          <v-col cols="12" class="mt-1">
            <v-radio-group
              v-model="platform"
              inline
              color="primary"
              hide-details
            >
              <v-radio label="Website" value="web" />
              <v-radio label="Mobile" value="mobile" />
            </v-radio-group>
          </v-col>

          <v-col cols="12" class="mt-2">
            <v-btn
              size="small"
              variant="tonal"
              class="text-none mb-2"
              @click="() => toggleSelectAll(!isAllSelected)"
            >
              {{ isAllSelected ? 'Unselect All' : 'Select All' }}
            </v-btn>
          </v-col>

          <v-col cols="12" class="mt-3">
            <v-card variant="outlined" border="thin" rounded="lg">
              <template
                v-for="(actions, resourceKey, resourceIndex) in safePermissions"
                :key="resourceKey"
              >
                <v-divider v-if="resourceIndex > 0" />

                <!-- Category row -->
                <v-list-item density="compact" :ripple="false">
                  <template #prepend>
                    <v-chip class="mr-3" size="small" label>
                      {{ selectedActionCount(String(resourceKey)) }}
                    </v-chip>
                  </template>
                  <v-list-item-title>
                    <span
                      class="text-capitalize text-subtitle-2 font-weight-medium"
                    >
                      {{ String(resourceKey).replace(/-/g, " ") }}
                    </span>
                  </v-list-item-title>
                  <template #append>
                    <v-switch
                      :model-value="isCategoryEnabled(String(resourceKey))"
                      @update:model-value="
                        toggleCategory(String(resourceKey), $event)
                      "
                      color="green"
                      density="compact"
                      hide-details
                      inset
                    />
                  </template>
                </v-list-item>

                <!-- Expanded checkboxes when toggled on -->
                <template v-if="isCategoryEnabled(String(resourceKey))">
                  <template
                    v-for="([actionKey, action]) in Object.entries(actions || {})"
                    :key="actionKey"
                  >
                    <v-divider />
                    <v-list-item density="compact" :ripple="false">
                      <template #prepend>
                        <v-checkbox-btn
                          :model-value="permState.selected.includes(`${String(resourceKey)}:${String(actionKey)}`)"
                          @update:model-value="
                            toggleAction(
                              String(resourceKey),
                              String(actionKey),
                              $event
                            )
                          "
                          color="primary"
                          density="compact"
                          class="mr-2"
                        />
                      </template>
                      <v-list-item-title
                        class="text-subtitle-2 font-weight-medium text-capitalize"
                      >
                        {{ String(actionKey).replace(/-/g, " ") }}
                      </v-list-item-title>
                      <v-list-item-subtitle class="text-caption">
                        {{ action.description }}
                      </v-list-item-subtitle>
                    </v-list-item>
                  </template>
                </template>
              </template>
            </v-card>
          </v-col>

          <v-col cols="12" class="my-2">
            <v-row no-gutters>
              <v-col cols="12" class="text-center">
                <span
                  class="text-none text-subtitle-2 font-weight-medium text-error"
                >
                  {{ message }}
                </span>
              </v-col>
            </v-row>
          </v-col>
        </v-row>
      </v-form>
    </v-card-text>

    <v-toolbar class="pa-0" density="compact">
      <v-row no-gutters>
        <v-col cols="6" class="pa-0">
          <v-btn
            block
            variant="text"
            class="text-none"
            size="large"
            height="48"
            @click="cancel"
          >
            Cancel
          </v-btn>
        </v-col>

        <v-col cols="6" class="pa-0">
          <v-btn
            block
            variant="flat"
            color="black"
            class="text-none font-weight-bold rounded-0"
            height="48"
            :disabled="!validForm"
            :loading="disable"
            @click="submit"
          >
            Submit
          </v-btn>
        </v-col>
      </v-row>
    </v-toolbar>
  </v-card>
</template>

<script setup lang="ts">
import useRole from "../composables/useRole";
import useUtils from "../composables/useUtils";
import useSite from "../composables/useSite";

const props = defineProps({
  permissions: {
    type: Object,
    default: () => ({}),
  },
  org: {
    type: String,
    default: "",
  },
  siteId: {
    type: String,
    default: "",
  },
  type: {
    type: String,
    default: "app",
  },
  siteState: {
    type: Boolean,
    default: true,
  },
});

const emit = defineEmits(["cancel", "success", "success:create-more"]);

const validForm = ref(false);
const name = ref("");
const platform = ref("web");
const disable = ref(false);
const message = ref("");

const { requiredRule } = useUtils();
const { createRole } = useRole();
const { getSiteById } = useSite();

// All selected + enabled 1 shallowRef
const permState = shallowRef({
  selected: [] as string[],
  enabled: [] as string[],
})

function isCategoryEnabled(resource: string) {
  return permState.value.enabled.includes(resource)
}

function selectedActionCount(resource: string) {
  return permState.value.selected.filter(p => p.startsWith(`${resource}:`)).length
}

function toggleCategory(resource: string, value: boolean | null) {
  const { selected, enabled } = permState.value
  if (value) {
    if (!enabled.includes(resource)) {
      permState.value = { selected, enabled: [...enabled, resource] }
    }
  } else {
    permState.value = {
      selected: selected.filter(p => !p.startsWith(`${resource}:`)),
      enabled: enabled.filter(r => r !== resource),
    }
  }
}

function toggleAction(resource: string, action: string, value: boolean | null) {
  if (value !== true && value !== false) return
  const key = `${resource}:${action}`
  const { selected, enabled } = permState.value
  if (value) {
    if (!selected.includes(key)) {
      permState.value = { selected: [...selected, key], enabled }
    }
  } else {
    permState.value = { selected: selected.filter(p => p !== key), enabled }
  }
}

function toggleSelectAll(value: boolean) {
  if (!value) {
    permState.value = { selected: [], enabled: [] }
    return
  }

  const perms = safePermissions.value
  if (!perms) return

  const allKeys: string[] = []
  const categories: string[] = []

  for (const [resource, actions] of Object.entries(perms)) {
    if (!resource || !actions || typeof actions !== 'object') continue
    categories.push(resource)
    for (const action of Object.keys(actions)) {
      if (action) allKeys.push(`${resource}:${action}`)
    }
  }

  // 1 assignment to trigger reactivity only once
  permState.value = { selected: allKeys, enabled: categories }
}

const siteName = ref("");
const loadSite = ref(false);

watch(
  () => props.siteId,
  async (id) => {
    if (!id) {
      siteName.value = "";
      return;
    }
    loadSite.value = true;
    try {
      const site = await getSiteById(id);
      siteName.value = site?.name ?? id;
    } catch {
      siteName.value = id;
    } finally {
      loadSite.value = false;
    }
  },
  { immediate: true }
);

async function submit() {
  disable.value = true;
  try {
    const platformValue = platform.value === "web" ? "website" : platform.value;
    await createRole({
      name: name.value,
      permissions: permState.value.selected,
      type: props.type,
      org: props.org,
      site: props.siteId,
      platform: platformValue,
    });
    emit("success");
  } catch (error: any) {
    message.value = error.response._data.message;
  } finally {
    disable.value = false;
  }
}

function cancel() {
  name.value = ""
  permState.value = { selected: [], enabled: [] }
  platform.value = "web"
  message.value = ""
  emit("cancel")
}

const safePermissions = computed(() => {
  const p = props.permissions || {}
  const cleaned: Record<string, any> = {}

  for (const [k, v] of Object.entries(p)) {
    if (v && typeof v === 'object' && !Array.isArray(v)) {
      cleaned[k] = v
    } else {
      cleaned[k] = {}
    }
  }

  return cleaned
})

const isAllSelected = computed(() => {
  const perms = safePermissions.value
  const allKeys: string[] = []

  Object.entries(perms).forEach(([resource, actions]) => {
    if (!actions) return
    Object.keys(actions).forEach((action) => {
      if (action) allKeys.push(`${resource}:${action}`)
    })
  })

  return allKeys.length > 0 &&
    allKeys.every(k => permState.value.selected.includes(k))
})

</script>
