<template>
  <Snackbar v-model="snackbar" :text="snackbarMessage" :color="snackbarColor" />

  <AccessCardDetailsDialog
    v-model="historyDialog"
    :card="selectedCardInUnit"
    :site-id="siteId"
  />

  <!-- Assign to Person Dialog -->
  <v-dialog :model-value="showAssignForm" width="420" persistent>
    <v-card width="100%">
      <v-toolbar density="compact" color="surface">
        <v-row no-gutters class="fill-height px-4" align="center">
          <span class="font-weight-bold">Assign Card to Person</span>
        </v-row>
      </v-toolbar>

      <v-card-text class="pa-4">
        <div class="text-caption text-grey mb-4">
          Card: <strong class="text-body-2 text-black">{{ selectedCardInUnit?.cardNo }}</strong>
        </div>

        <!-- Person Type Filter -->
        <!-- <div class="text-caption font-weight-bold mb-1 text-uppercase text-grey-darken-1">Person Type</div>
        <v-btn-toggle
          v-model="assignPersonType"
          color="primary"
          density="compact"
          variant="outlined"
          rounded="pill"
          class="mb-4"
        >
          <v-btn value="" size="small" class="text-none px-3">All</v-btn>
          <v-btn value="owner" size="small" class="text-none px-3">Unit Owner</v-btn>
          <v-btn value="resident" size="small" class="text-none px-3">Resident</v-btn>
          <v-btn value="tenant" size="small" class="text-none px-3">Tenant</v-btn>
        </v-btn-toggle> -->

        <!-- Person Selector -->
        <div class="text-caption font-weight-bold mb-1 text-uppercase text-grey-darken-1">
          Person <span class="text-error">*</span>
        </div>
        <v-autocomplete
          v-model="assignPerson"
          :items="filteredPeopleItems"
          density="compact"
          item-title="name"
          item-value="_id"
          hide-details="auto"
          placeholder="Select person..."
          persistent-placeholder
          :loading="peopleLoading"
          return-object
          no-data-text="No residents or tenants found for this unit"
        >
          <template #item="{ props: itemProps, item }">
            <v-list-item v-bind="itemProps" :subtitle="personTypeLabel(item.raw)" />
          </template>
          <template #selection="{ item }">
            <span>{{ item.raw.name }}</span>
            <v-chip size="x-small" class="ml-2" color="grey" variant="tonal">
              {{ personTypeLabel(item.raw) }}
            </v-chip>
          </template>
        </v-autocomplete>
        <p v-if="assignError" class="text-error text-caption mt-2">{{ assignError }}</p>
      </v-card-text>

      <v-toolbar density="compact">
        <v-row no-gutters>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="text"
              class="text-none"
              height="48"
              @click="cancelAssign"
            >
              Cancel
            </v-btn>
          </v-col>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="flat"
              color="black"
              class="text-none"
              height="48"
              :disabled="!assignPerson || assignLoading"
              :loading="assignLoading"
              @click="confirmAssign"
            >
              Assign
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <v-dialog :model-value="modelValue" width="450" persistent>
    <v-card width="100%">
      <v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
        <v-row no-gutters class="mb-4">
          <v-col cols="12">
            <strong>Building:</strong> {{ unit?.block?.name ?? "N/A" }}
          </v-col>
          <v-col cols="12">
            <strong>Level:</strong> {{ unit?.level?.level ?? "N/A" }}
          </v-col>
          <v-col cols="12">
            <strong>Unit:</strong> {{ unit?.name ?? "N/A" }}
          </v-col>

          <!-- Available Physical -->
          <v-col cols="12" class="mt-3">
            <strong>Available Physical</strong>
            <div v-if="unit?.available?.physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.available.physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Available Non-Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Available Non-Physical</strong>
            <div v-if="unit?.available?.non_physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.available.non_physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Assigned Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Assigned Physical</strong>
            <div v-if="unit?.assigned?.physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.assigned.physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Assigned Non-Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Assigned Non-Physical</strong>
            <div v-if="unit?.assigned?.non_physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.assigned.non_physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Replaced Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Replaced Physical</strong>
            <div v-if="unit?.replaced?.physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.replaced.physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'orange' : 'orange'"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Replaced Non-Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Replaced Non-Physical</strong>
            <div v-if="unit?.replaced?.non_physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.replaced.non_physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'orange' : 'orange'"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Deleted Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Deleted Physical</strong>
            <div v-if="unit?.deleted?.physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.deleted.physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'red' : 'red'"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>

          <!-- Deleted Non-Physical -->
          <v-col cols="12" class="mt-2">
            <strong>Deleted Non-Physical</strong>
            <div v-if="unit?.deleted?.non_physical?.length" class="mt-1">
              <v-chip
                v-for="card in unit.deleted.non_physical"
                :key="card._id"
                size="small"
                class="mr-1 mb-1"
                :color="selectedCardInUnit?._id === card._id ? 'red' : 'red'"
                :variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
                style="cursor: pointer"
                @click="toggleCard(card)"
              >
                {{ card.cardNo }}
              </v-chip>
            </div>
            <span v-else class="text-caption text-grey ml-1">None</span>
          </v-col>
        </v-row>
      </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="emit('update:modelValue', false)"
            >
              Close
            </v-btn>
          </v-col>
          <v-col cols="6" class="pa-0" v-if="canUpdate">
            <v-menu>
              <template #activator="{ props }">
                <v-btn
                  block
                  variant="flat"
                  color="black"
                  class="text-none"
                  height="48"
                  v-bind="props"
                  tile
                >
                  More actions
                </v-btn>
              </template>
              <v-list class="pa-0">
                <v-list-item
                  v-if="canAssignToPerson && isSelectedCardAvailable"
                  @click="openAssignForm"
                >
                  <v-list-item-title class="text-subtitle-2">
                    Assign to Person
                  </v-list-item-title>
                </v-list-item>
                <v-list-item
                  :disabled="!isSelectedCardAssignedPhysical"
                  @click="emit('replace')"
                  v-if="canReplaceAccessCard && isSelectedCardAssignedPhysical"
                >
                  <v-list-item-title class="text-subtitle-2">
                    Replace Card
                  </v-list-item-title>
                </v-list-item>
                <v-list-item :disabled="!isSelectedCardPhysical" @click="historyDialog = true">
                  <v-list-item-title class="text-subtitle-2 cursor-pointer">
                    Card Details
                  </v-list-item-title>
                </v-list-item>
                <v-list-item
                  @click="emit('delete')"
                  class="text-red"
                  :disabled="!isSelectedCardDeletable"
                  v-if="canDeleteAccessCard"
                >
                  <v-list-item-title class="text-subtitle-2">
                    Delete Card
                  </v-list-item-title>
                </v-list-item>
              </v-list>
            </v-menu>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>
</template>

<script setup lang="ts">
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  unit: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({}),
  },
  selectedCardInUnit: {
    type: Object as PropType<Record<string, any> | null>,
    default: null,
  },
  canUpdate: {
    type: Boolean,
    default: true,
  },
  canReplaceAccessCard: {
    type: Boolean,
    default: true,
  },
  canDeleteAccessCard: {
    type: Boolean,
    default: true,
  },
  canAssignToPerson: {
    type: Boolean,
    default: true,
  },
  isSelectedCardAssignedPhysical: {
    type: Boolean,
    default: false,
  },
  isSelectedCardPhysical: {
    type: Boolean,
    default: false,
  },
  siteId: {
    type: String,
    default: "",
  },
  orgId: {
    type: String,
    default: "",
  },
});

const emit = defineEmits<{
  "update:modelValue": [value: boolean];
  "update:selectedCardInUnit": [value: Record<string, any> | null];
  replace: [];
  delete: [];
  refresh: [];
  "assign-to-person": [{ card: Record<string, any> | null; person: Record<string, any> | null }];
}>();

const { getResidents, assignUser } = useAccessManagement();

const historyDialog = ref(false);
const showAssignForm = ref(false);
const assignPersonType = ref<string>("");
const assignPerson = ref<Record<string, any> | null>(null);
const peopleItems = ref<Record<string, any>[]>([]);
const peopleLoading = ref(false);
const assignLoading = ref(false);
const assignError = ref("");
const encryptedAcmUrl = ref("");
const snackbar = ref(false);
const snackbarMessage = ref("");
const snackbarColor = ref<"success" | "error">("success");

function showToast(message: string, color: "success" | "error") {
  snackbarMessage.value = message;
  snackbarColor.value = color;
  snackbar.value = true;
}

const isSelectedCardAvailable = computed(() => {
  if (!props.selectedCardInUnit?._id) return false;
  const id = props.selectedCardInUnit._id;
  return [
    ...(props.unit?.available?.physical ?? []),
    ...(props.unit?.available?.non_physical ?? []),
  ].some((c) => c._id === id);
});

const isSelectedCardDeletable = computed(() => {
  if (!props.selectedCardInUnit?._id) return false;
  const id = props.selectedCardInUnit._id;
  return [
    ...(props.unit?.available?.physical ?? []),
    ...(props.unit?.available?.non_physical ?? []),
    ...(props.unit?.assigned?.physical ?? []),
    ...(props.unit?.assigned?.non_physical ?? []),
  ].some((c) => c._id === id);
});

const filteredPeopleItems = computed(() => {
  if (!assignPersonType.value) return peopleItems.value;
  if (assignPersonType.value === "owner") return peopleItems.value.filter((p) => p.isOwner);
  return peopleItems.value.filter((p) => p.type === assignPersonType.value && !p.isOwner);
});

const personTypeLabel = (person: Record<string, any>) => {
  if (person.isOwner) return "Unit Owner";
  if (person.type === "resident") return "Resident";
  if (person.type === "tenant") return "Tenant";
  return person.type ?? "";
};

async function openAssignForm() {
  showAssignForm.value = true;
  assignPerson.value = null;
  assignPersonType.value = "";
  assignError.value = "";
  peopleItems.value = [];
  encryptedAcmUrl.value = "";

  if (!props.unit?._id || !props.orgId || !props.siteId) return;
  peopleLoading.value = true;
  try {
    const [residentsRes, acmRes] = await Promise.all([
      getResidents({ orgId: props.orgId, siteId: props.siteId, unitId: props.unit._id }),
      $fetch<{ encrypted: string }>("/api/encrypt-acm-url"),
    ]);
    peopleItems.value = residentsRes?.data ?? [];
    encryptedAcmUrl.value = acmRes?.encrypted ?? "";
  } catch {
    peopleItems.value = [];
  } finally {
    peopleLoading.value = false;
  }
}

function cancelAssign() {
  showAssignForm.value = false;
  assignPerson.value = null;
  assignPersonType.value = "";
  assignError.value = "";
}

const selectedCardType = computed(() => {
  const id = props.selectedCardInUnit?._id;
  if (!id) return "QRCODE";
  const isPhysical = [
    ...(props.unit?.available?.physical ?? []),
    ...(props.unit?.assigned?.physical ?? []),
  ].some((c: any) => c._id === id);
  return isPhysical ? "NFC" : "QRCODE";
});

async function confirmAssign() {
  if (!assignPerson.value || !props.unit?._id) return;
  assignLoading.value = true;
  assignError.value = "";
  try {
    await assignUser({
      assignees: [assignPerson.value._id],
      unit: props.unit._id,
      type: selectedCardType.value,
      acm_url: encryptedAcmUrl.value,
    });
    emit("assign-to-person", {
      card: props.selectedCardInUnit,
      person: assignPerson.value,
    });
    showToast("Card assigned successfully.", "success");
    cancelAssign();
    emit("refresh");
  } catch (e: any) {
    const msg = e?.data?.message ?? "Failed to assign. Please try again.";
    assignError.value = msg;
    showToast(msg, "error");
  } finally {
    assignLoading.value = false;
  }
}

function toggleCard(card: Record<string, any>) {
  emit(
    "update:selectedCardInUnit",
    props.selectedCardInUnit?._id === card._id ? null : card
  );
}
</script>
