<template>
  <v-row no-gutters>
    <v-col cols="12" class="mb-2">
      <v-row no-gutters align="center" justify="space-between">
        <v-row no-gutters class="ga-2">
          <v-btn
            class="text-none"
            rounded="pill"
            variant="tonal"
            size="large"
            @click="setCard()"
            v-if="canCreate && canCreateAccessCard"
          >
            Add Access Card
          </v-btn>
          <v-btn
            class="text-none"
            rounded="pill"
            variant="tonal"
            size="large"
            @click="assignDialog = true"
            v-if="canCreate && canAssignAccessCard"
          >
            Assign to Unit
          </v-btn>
        </v-row>

        <v-text-field
          v-model="searchText"
          placeholder="Search Card, Unit..."
          variant="outlined"
          density="comfortable"
          clearable
          hide-details
          class="ml-2"
          style="max-width: 250px"
        />
      </v-row>
    </v-col>
    <!-- Available Card Stats -->
    <v-col cols="12" class="mb-2">
      <AccessCardAvailableStats ref="statsRef" :site-id="siteId" />
    </v-col>

    <v-col cols="12">
      <v-card
        width="100%"
        variant="outlined"
        border="thin"
        rounded="lg"
        :loading="loading"
      >
        <v-toolbar density="compact" color="grey-lighten-4">
          <template #prepend>
            <v-btn fab icon density="comfortable" @click="getCards">
              <v-icon>mdi-refresh</v-icon>
            </v-btn>
          </template>

          <template #append>
            <v-row no-gutters justify="end" align="center">
              <span class="mr-2 text-caption text-fontgray">
                {{ pageRange }}
              </span>
              <local-pagination
                v-model="page"
                :length="pages"
                @update:value="getCards"
              />
            </v-row>
          </template>
        </v-toolbar>
        <v-data-table
          :headers="headers"
          :items="items"
          item-value="_id"
          items-per-page="10"
          fixed-header
          hide-default-footer
          @click:row="tableRowClickHandler"
          style="max-height: calc(100vh - (200px))"
        />
      </v-card>
    </v-col>

    <!-- Create Dialog -->
    <v-dialog v-model="createDialog" width="650" persistent>
      <AccessCardAddForm
        @cancel="createDialog = false"
        @success="successCreate()"
        @error="(msg) => showMessage(msg, 'error')"
      />
    </v-dialog>

    <!-- Assign to Unit Dialog -->
    <v-dialog v-model="assignDialog" width="650" persistent>
      <AccessCardAssignToUnitForm
        :site-id="siteId"
        @cancel="assignDialog = false"
        @success="successAssign()"
        @error="(msg: any) => showMessage(msg, 'error')"
      />
    </v-dialog>

    <!-- Preview Dialog -->
    <AccessCardPreviewDialog
      v-model="previewDialog"
      :unit="selectedCard"
      v-model:selected-card-in-unit="selectedCardInUnit"
      :can-update="canUpdate"
      :can-replace-access-card="canReplaceAccessCard"
      :can-delete-access-card="canDeleteAccessCard"
      :is-selected-card-assigned-physical="isSelectedCardAssignedPhysical"
      :is-selected-card-physical="isSelectedCardPhysical"
      :site-id="siteId"
      :org-id="orgId"
      @replace="openReplaceDialog()"
      @delete="openDeleteDialog()"
      @refresh="handleAssignRefresh"
    />

    <!-- Replace Card Dialog -->
    <v-dialog v-model="replaceDialog" width="500" persistent>
      <AccessCardReplaceForm
        v-if="selectedCardInUnit"
        :card="selectedCardInUnit"
        :unit="selectedCard"
        :site-id="siteId"
        @cancel="replaceDialog = false"
        @success="successReplace()"
        @error="(msg: any) => showMessage(msg, 'error')"
      />
    </v-dialog>

    <!-- Delete Dialog -->
    <AccessCardDeleteDialog
      v-model="confirmDialog"
      :loading="deleteLoading"
      :error="deleteError"
      @confirm="handleDeleteCard"
    />

    <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
  </v-row>
</template>
<script setup lang="ts">
definePageMeta({
  middleware: ["01-auth", "02-org"],
  memberOnly: true,
});
const props = defineProps({
  headers: {
    type: Array as PropType<Array<Record<string, any>>>,
    default: () => [
      {
        title: "Block",
        value: "block.block",
      },
      {
        title: "Level",
        value: "level.level",
      },
      {
        title: "Unit",
        value: "name",
      },
      {
        title: "Avail. (P)",
        value: "cardCounts.available.physical",
      },
      {
        title: "Avail. (NP)",
        value: "cardCounts.available.non_physical",
      },
      {
        title: "Asgn. (P)",
        value: "cardCounts.assigned.physical",
      },
      {
        title: "Asgn. (NP)",
        value: "cardCounts.assigned.non_physical",
      },
      {
        title: "Total",
        value: "totalCardCount",
      },
      // { title: "Action", value: "action-table" },
    ],
  },
  canCreate: {
    type: Boolean,
    default: true,
  },
  canUpdate: {
    type: Boolean,
    default: true,
  },
  canDelete: {
    type: Boolean,
    default: true,
  },
  canCreateAccessCard: {
    type: Boolean,
    default: true,
  },
  canDeleteAccessCard: {
    type: Boolean,
    default: true,
  },
  canReplaceAccessCard: {
    type: Boolean,
    default: true,
  },
  canAssignAccessCard: {
    type: Boolean,
    default: true,
  },
});

// const { headerSearch } = useLocal();
const page = ref(1);
const pages = ref(0);
const pageRange = ref("-- - -- of --");

const message = ref("");
const messageSnackbar = ref(false);
const messageColor = ref("");

const items = ref<Array<Record<string, any>>>([]);
const createDialog = ref(false);
const assignDialog = ref(false);
const previewDialog = ref(false);
const deleteLoading = ref(false);
const deleteError = ref("");
const confirmDialog = ref(false);
const searchText = ref("");
const replaceDialog = ref(false);

const route = useRoute();
//@TODO
const siteId = computed(() => route.params.site as string);
// const siteId = computed(() => "66ab2f1381856008f1887971" as string);
const orgId = computed(() => route.params.org as string);

const selectedCard = ref<Record<string, any>>({});
const selectedCardInUnit = ref<Record<string, any> | null>(null);
const selectedCardId = ref<string | null>(null);

watch(previewDialog, (val) => {
  if (!val) selectedCardInUnit.value = null;
});

const isSelectedCardAssignedPhysical = computed(() =>
  selectedCard.value?.assigned?.physical?.some(
    (c: any) => c._id === selectedCardInUnit.value?._id
  ) ?? false
);

const isSelectedCardPhysical = computed(() =>
  ["available", "assigned", "replaced", "deleted"].some((state) =>
    selectedCard.value?.[state]?.physical?.some(
      (c: any) => c._id === selectedCardInUnit.value?._id
    )
  )
);

const { getUserTypeAccessCards, deleteCard: _deleteCard } = useAccessManagement();

const statsRef = ref<{ refresh: () => void } | null>(null);

const {
  data: getCardReq,
  refresh: getCards,
  status: getAllReqStatus,
} = useLazyAsyncData(
  "get-all-cards",
  () =>
    getUserTypeAccessCards({
      page: page.value,
      search: searchText.value,
      organization: orgId.value,
      site: siteId.value,
      userType: "Visitor/Resident",
    }),
  {
    watch: [page, searchText],
  }
);

const loading = computed(() => getAllReqStatus.value === "pending");

watchEffect(() => {
  if (getCardReq.value?.data) {
    items.value = getCardReq.value.data.items;
    pages.value = getCardReq.value.data.pages;
    pageRange.value = getCardReq.value.data.pageRange;
  }
});

function setCard({ mode = "create", dialog = true, data = {} as TCard } = {}) {
  if (mode === "create") {
    createDialog.value = dialog;
  } else if (mode === "preview") {
    previewDialog.value = dialog;
    selectedCard.value = data;
  }
}

async function handleAssignRefresh() {
  await getCards();
  await nextTick();
  statsRef.value?.refresh();
  const updated = items.value.find((item: any) => item._id === selectedCard.value?._id);
  if (updated) selectedCard.value = updated;
  previewDialog.value = true;
}

function successCreate() {
  createDialog.value = false;
  getCards();
  statsRef.value?.refresh();
  showMessage("Card created successfully!", "success");
}

function successAssign() {
  assignDialog.value = false;
  getCards();
  statsRef.value?.refresh();
  showMessage("Access card assigned successfully!", "success");
}

function showMessage(msg: string, color: string) {
  message.value = msg;
  messageColor.value = color;
  messageSnackbar.value = true;
}

function tableRowClickHandler(_: any, data: any) {
  selectedCard.value = data.item as TCard;
  previewDialog.value = true;
}

function openDeleteDialog() {
  confirmDialog.value = true;
  deleteError.value = "";
}

function openReplaceDialog() {
  replaceDialog.value = true;
}

function successReplace() {
  replaceDialog.value = false;
  previewDialog.value = false;
  getCards();
  statsRef.value?.refresh();
  showMessage("Access card replaced successfully!", "success");
}

async function handleDeleteCard(remarks: string) {
  deleteLoading.value = true;
  try {
    await _deleteCard({ cardId: selectedCardInUnit.value?._id ?? "", remarks });
    await getCards();
    statsRef.value?.refresh();
    selectedCardId.value = null;
    confirmDialog.value = false;
    previewDialog.value = false;
    showMessage("Access card deleted successfully!", "success");
  } catch (error: any) {
    const msg = error?.response?._data?.message || "Failed to delete card";
    deleteError.value = msg;
    showMessage(msg, "error");
  } finally {
    deleteLoading.value = false;
  }
}
</script>
