<template>
  <v-card width="100%">
    <v-toolbar>
      <v-row no-gutters class="fill-height px-6" align="center" justify="space-between">
        <span class="font-weight-bold text-h5 text-capitalize">
          {{ prop.mode }} Access Card
        </span>
        <v-btn-toggle
          v-if="prop.mode === 'add'"
          v-model="uploadMode"
          mandatory
          color="primary"
          density="compact"
          rounded="pill"
          variant="outlined"
        >
          <v-btn value="single" size="small" class="text-none px-4">Single</v-btn>
          <v-btn value="bulk" size="small" class="text-none px-4">Bulk Upload</v-btn>
        </v-btn-toggle>
      </v-row>
    </v-toolbar>
    <v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-0">
      <!-- Bulk Upload Mode -->
      <template v-if="uploadMode === 'bulk'">
        <v-row no-gutters class="px-6 pt-4 pb-2">
          <v-col cols="12" class="px-1 mb-2">
            <v-progress-linear v-if="templateLoading" indeterminate color="primary" class="mb-2" />
            <v-alert
              v-else-if="!entryPassTemplate.id"
              type="warning"
              variant="tonal"
              density="compact"
              icon="mdi-alert-outline"
            >
              No upload template has been configured. Please upload a template in
              <strong>Entry Pass Settings</strong> before using bulk upload.
            </v-alert>
            <template v-else-if="entryPassTemplate.id">
              <InputLabel
                class="text-capitalize font-weight-bold"
                title="Download Template"
              />
              <div class="d-flex align-center mt-1">
                <v-icon size="20" class="mr-2 text-primary">mdi-paperclip</v-icon>
                <a
                  href="#"
                  class="text-primary text-decoration-none text-body-2"
                  @click.prevent="downloadBulkTemplate"
                >
                  {{ entryPassTemplate.name }}
                </a>
                <v-btn
                  icon
                  density="compact"
                  variant="text"
                  size="small"
                  class="ml-1"
                  @click.prevent="downloadBulkTemplate"
                >
                  <v-icon size="18">mdi-download</v-icon>
                </v-btn>
              </div>

              <!-- Column Guide -->
              <div class="mt-3">
                <p class="text-caption font-weight-bold text-grey-darken-2 mb-1 text-uppercase">
                  Template Column Guide
                </p>
                <v-table density="compact" class="text-caption rounded border">
                  <thead>
                    <tr class="bg-grey-lighten-4">
                      <th class="text-left text-caption font-weight-bold py-1 px-2">Column</th>
                      <th class="text-left text-caption font-weight-bold py-1 px-2">Format / Accepted Values</th>
                      <th class="text-left text-caption font-weight-bold py-1 px-2">Example</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="col in templateColumnGuide" :key="col.name">
                      <td class="py-1 px-2 font-weight-medium" style="white-space: nowrap">{{ col.name }}</td>
                      <td class="py-1 px-2 text-grey-darken-1">{{ col.format }}</td>
                      <td class="py-1 px-2 text-grey-darken-2">{{ col.example }}</td>
                    </tr>
                  </tbody>
                </v-table>
              </div>
            </template>
          </v-col>
          <v-col cols="12" class="px-1 mt-2">
            <InputLabel
              class="text-capitalize font-weight-bold"
              title="Upload File"
              required
            />
            <v-file-input
              v-model="bulkFile"
              density="compact"
              hide-details="auto"
              accept=".xlsx,.xls,.csv"
              placeholder="Select file to upload..."
              prepend-icon=""
              prepend-inner-icon="mdi-tray-arrow-up"
              :rules="[requiredRule]"
              :disabled="!entryPassTemplate.id || templateLoading"
            />
            <v-alert
              v-if="!templateLoading && !entryPassTemplate.id"
              type="info"
              variant="text"
              density="compact"
              class="mt-1 px-0"
            >
              Upload is disabled until a template is configured.
            </v-alert>
          </v-col>
        </v-row>
      </template>

      <!-- Single Add Mode -->
      <v-form v-if="uploadMode === 'single'" v-model="validForm" :disabled="disable">
        <v-row no-gutters class="px-6 pt-4">
          <v-col cols="12" class="px-1">
            <InputLabel
              class="text-capitalize font-weight-bold"
              title="Type of Access Card"
              required
            />
            <v-select
              v-model.number="card.accessCardType"
              :items="accessCardTypes"
              density="comfortable"
              :rules="[requiredRule]"
              type="text"
            ></v-select>
          </v-col>
          <v-col cols="12" class="px-1" v-if="isNonPhysicalCard">
            <InputLabel
              class="text-capitalize font-weight-bold"
              title="Quantity"
              required
            />
            <v-text-field
              v-model.number="card.quantity"
              density="compact"
              hide-details
              :rules="[requiredRule]"
              type="number"
              :min="1"
              hide-spin-buttons
              @blur="enforceMinQuantity"
            />
          </v-col>
          <v-col cols="12" class="px-1 pb-5" v-if="!isNonPhysicalCard">
            <InputLabel
              class="text-capitalize font-weight-bold"
              :title="`Card No (${cardNoMaxLength} digits)`"
              required
            />
            <v-text-field
              v-model="card.cardNumber"
              density="compact"
              hide-details
              :rules="[requiredRule]"
              :maxlength="cardNoMaxLength"
              type="number"
              hide-spin-buttons
              :suffix="`${card.cardNumber?.toString().length || 0}/${cardNoMaxLength}`"
              @input="limitCardNumber"
            >
            </v-text-field>
          </v-col>
          <v-col cols="12" class="px-1" v-if="!isNonPhysicalCard">
            <InputLabel
              class="text-capitalize font-weight-bold"
              title="Start Date"
              required
            />
            <InputDatePicker
              v-model="card.startDate"
              placeholder="Start Date"
              :rules="[requiredRule]"
              @update:model-value="updateEndDate"
            />
          </v-col>
          <v-col cols="12" class="px-1 pb-4" v-if="!isNonPhysicalCard">
            <InputLabel
              class="text-capitalize font-weight-bold"
              title="End Date"
              required
            />
            <InputDatePicker
              v-model="card.endDate"
              placeholder="End Date"
              :rules="[requiredRule]"
              readonly
            />
          </v-col>
          <v-divider />
          <v-row class="py-8 px-0">
            <v-col cols="12">
              <InputLabel
                class="text-capitalize font-weight-bold"
                title="Door Location"
                required
              />
              <v-select
                v-model="card.door"
                density="compact"
                :items="accessLevelItems"
                item-title="name"
                item-value="no"
                hide-details
                :rules="[requiredRule]"
              >
              </v-select>
            </v-col>
            <v-col cols="12">
              <InputLabel
                class="text-capitalize font-weight-bold"
                title="Access Group"
                required
              />
              <v-select
                v-model="card.accessGroup"
                density="compact"
                :items="accessGroupItems"
                item-title="name"
                item-value="name"
                hide-details
                :rules="[requiredRule]"
                multiple
              >
              </v-select>
            </v-col>
            <v-col cols="12" v-if="!isNonPhysicalCard">
              <InputLabel
                class="text-capitalize font-weight-bold"
                title="Card Type"
                required
              />
              <v-select
                v-model="card.cardType"
                density="compact"
                :items="cardTypeItems"
                hide-details
                :rules="[requiredRule]"
                item-title="name"
                item-value="value"
              >
              </v-select>
            </v-col>
            <v-col cols="12" v-if="!isNonPhysicalCard">
              <InputLabel
                class="text-capitalize font-weight-bold"
                :title="`Pin No (${cardPinMaxLength} digits)`"
                required
              />
              <v-text-field
                v-model="card.pinNo"
                density="compact"
                hide-details
                :rules="[requiredRule]"
                :maxlength="cardPinMaxLength"
                type="number"
                hide-spin-buttons
                :suffix="`${card.pinNo?.toString().length || 0}/${cardPinMaxLength}`"
                @input="limitPinNo"
              >
              </v-text-field>
            </v-col>
            <v-col cols="12" class="pt-5">
              <v-switch
                v-model="card.useAsLiftCard"
                label="Use as Lift Card"
                color="primary"
                hide-details
                density="compact"
              />
            </v-col>
            <v-col cols="12" v-if="card.useAsLiftCard">
              <InputLabel
                class="text-capitalize font-weight-bold"
                title="Lift Access Level"
                :required="card.useAsLiftCard"
              />
              <v-select
                v-model="card.liftAccessLevel"
                density="compact"
                :items="liftAccessLevelItems"
                hide-details
                :rules="card.useAsLiftCard ? [requiredRule] : []"
                item-title="name"
                item-value="no"
              />
            </v-col>
            <v-col cols="12">
              <div
                class="d-flex justify-space-between align-center rounded px-0"
              >
                <span class="d-flex align-center"
                  >Activate
                  <v-checkbox
                    v-model="card.isActivate"
                    label="Yes"
                    class="d-flex align-center"
                  ></v-checkbox
                ></span>
                <span class="d-flex align-center">
                  Anti Pass Back
                  <v-icon class="ml-1" color="grey" size="small"
                    >mdi-help-circle</v-icon
                  >
                  <v-checkbox
                    v-model="card.isAntiPassBack"
                    label="Yes"
                    class="d-flex align-center"
                  ></v-checkbox>
                </span>
              </div>
            </v-col>
            <v-col cols="12">
              <v-divider class="my-4" />
            </v-col>
            <v-col cols="12">
              <v-switch
                v-model="card.showAssign"
                label="Assign (Optional)"
                color="primary"
                hide-details
                density="compact"
              />
            </v-col>
            <template v-if="card.showAssign">
              <v-col cols="12">
                <InputLabel
                  class="text-capitalize font-weight-bold"
                  title="Block"
                />
                <v-autocomplete
                  v-model="card.assignBuilding"
                  density="compact"
                  :items="buildingItems"
                  hide-details
                  item-title="name"
                  item-value="value"
                  placeholder="Search building..."
                />
              </v-col>
              <v-col cols="12">
                <InputLabel
                  class="text-capitalize font-weight-bold"
                  title="Level"
                />
                <v-autocomplete
                  v-model="card.assignLevel"
                  density="compact"
                  :items="levelItems"
                  hide-details
                  item-title="name"
                  item-value="value"
                  placeholder="Search level..."
                  :disabled="!card.assignBuilding"
                />
              </v-col>
              <v-col cols="12">
                <InputLabel
                  class="text-capitalize font-weight-bold"
                  title="Unit"
                />
                <v-autocomplete
                  v-model="card.assignUnit"
                  density="compact"
                  :items="unitItems"
                  hide-details
                  item-title="name"
                  item-value="value"
                  placeholder="Search unit..."
                  :disabled="!card.assignLevel"
                />
              </v-col>
            </template>
          </v-row>
        </v-row>
      </v-form>
    </v-card-text>
    <v-toolbar density="compact">
      <v-row no-gutters>
        <v-col cols="6">
          <v-btn
            tile
            block
            variant="text"
            class="text-none"
            size="48"
            @click="cancel"
            :disabled="disable"
          >
            Cancel
          </v-btn>
        </v-col>

        <v-col cols="6">
          <v-btn
            tile
            block
            variant="flat"
            color="black"
            class="text-none"
            size="48"
            :disabled="(uploadMode === 'single' ? !validForm : !bulkFile || !entryPassTemplate.id || templateLoading) || disable"
            @click="submit"
            :loading="disable"
          >
            Submit
          </v-btn>
        </v-col>
      </v-row>
    </v-toolbar>
  </v-card>
</template>
<script setup lang="ts">
const prop = defineProps({
  mode: {
    type: String,
    default: "add",
  },
  card: {
    type: Object as PropType<TCard>,
    default: () => ({
      name: "",
      accessCardType: "",
      // visitorType: "",
      status: "active",
    }),
  },
});

const { add: _addCard, updateById: _updateCardById } = useCard();
const {
  getDoorAccessLevels: _getDoorAccessLevels,
  getLiftAccessLevels: _getLiftAccessLevels,
  getAccessGroups: _getAccessGroups,
  addPhysicalCard: _addPhysicalCard,
  addNonPhysicalCard: _addNonPhysicalCard,
  bulkPhysicalAccessCard: _bulkPhysicalAccessCard,
  getBlockLevelUnitList: _getBlockLevelUnitList,
} = useAccessManagement();
const { getBySiteId: _getEntryPassSettings } = useSiteEntryPassSettings();
const { getFileUrl } = useFile();

const config = useRuntimeConfig();
const emit = defineEmits(["cancel", "success", "error"]);

const validForm = ref(false);
const disable = ref(false);
const message = ref("");

// Bulk upload mode state
const uploadMode = ref<"single" | "bulk">("single");
const bulkFile = ref<File | null>(null);
const entryPassTemplate = ref<{ id: string; name: string }>({ id: "", name: "" });

const templateColumnGuide = [
  { name: "startDate",       format: "MM/DD/YYYY",                                              example: "02/26/2026" },
  { name: "endDate",         format: "MM/DD/YYYY",                                              example: "02/26/2036" },
  { name: "cardNo",          format: "Number 0 – 65535",                                        example: "301" },
  { name: "facilityCode",   format: "Number 0 – 255",                                          example: "11" },
  { name: "pin",             format: "6-digit number",                                          example: "123456" },
  { name: "accessLevel",     format: "Number (access level ID)",                               example: "1" },
  { name: "userType",        format: "Contractor | Visitor | Resident/Tenant | Visitor/Resident", example: "Visitor/Resident" },
  { name: "accessGroup",     format: "Group name (e.g. Full Access, No Access)",               example: "Full Access" },
  { name: "isLiftCard",      format: "TRUE or FALSE",                                          example: "FALSE" },
  { name: "liftAccessLevel", format: "Number (lift level ID) — required if isLiftCard is TRUE", example: "1" },
  { name: "Door Name",       format: "Name of the door",                                       example: "Main Door" },
  { name: "Lift Name",       format: "Name of the lift — required if isLiftCard is TRUE",      example: "Main Lift" },
];

const { requiredRule } = useUtils();

function formatDate(date: Date): string {
  return date.toISOString().split("T")[0];
}

const today = new Date();
const tenYearsLater = new Date(today);
tenYearsLater.setFullYear(today.getFullYear() + 10);

const card = ref<Record<string, any>>({
  accessCardType: "Physical Access Card",
  type: "door-setup",
  cardNumber: "",
  startDate: formatDate(today),
  endDate: formatDate(tenYearsLater),
  door: "",
  accessGroup: [],
  cardType: "Normal",
  pinNo: "",
  isActivate: true,
  isAntiPassBack: false,
  useAsLiftCard: false,
  isWinsland: false,
  status: "active",
  liftAccessLevel: "",
  org: "",
  site: "",
  unit: "",
  assign: "",
  quantity: 1,
  showAssign: false,
  assignBuilding: "",
  assignLevel: "",
  assignUnit: "",
});

const isNonPhysicalCard = computed(() => card.value.accessCardType === "Non Physical Access Card");

if (prop.mode === "edit") {
  card.value.accessCardType = prop.card.accessCardType;
  card.value.type = prop.card.type;
  card.value.cardNumber = prop.card.cardNumber;
  card.value.startDate = prop.card.startDate;
  card.value.endDate = prop.card.endDate;
  card.value.door = prop.card.door;
  card.value.accessGroup = prop.card.accessGroup;
  card.value.cardType = prop.card.cardType;
  card.value.pinNo = prop.card.pinNo;
  card.value.isActivate = prop.card.isActivate;
  card.value.isAntiPassBack = prop.card.isAntiPassBack;
  card.value.useAsLiftCard = prop.card.useAsLiftCard;
  card.value.status = prop.card.status;
  card.value.liftAccessLevel = prop.card.liftAccessLevel;
  card.value.org = prop.card.org;
  card.value.site = prop.card.site;
  card.value.unit = prop.card.unit;
  card.value.assign = prop.card.assign;
  card.value.quantity = prop.card.quantity;
  card.value.showAssign = prop.card.showAssign;
  card.value.assignBuilding = prop.card.assignBuilding;
  card.value.assignLevel = prop.card.assignLevel;
  card.value.assignUnit = prop.card.assignUnit;
}

const accessCardTypes = ["Physical Access Card", "Non Physical Access Card"];
const typeOfVisitors = ["Contractor", "Visitor"];

const accessLevelItems = ref<{ name: string; no: string }[]>([
]);
const accessGroupItems = ref([]);
const cardTypeItems = ref([
  {
    name: "Normal - Access Card",
    value: "Normal",
  },
  {
    name: "Special - Arm/Disarm Card",
    value: "Special",
  },
  {
    name: "Master - Master Card",
    value: "Master",
  },
  {
    name: "Maintenance - Maintenance Card",
    value: "Maintenance",
  },
]);
const cardNoMaxLength = ref(10);
const cardPinMaxLength = ref(6);
const liftAccessLevelItems = ref<{ name: string; no: string }[]>([]);
const buildingItems = ref<{ name: string; value: string }[]>([]);
const levelItems = ref<{ name: string; value: string }[]>([]);
const unitItems = ref<{ name: string; value: string }[]>([]);
const blockLevelUnitData = ref<any[]>([]);
const encryptedAcmUrl = ref("");

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

const templateLoading = ref(false);

async function fetchEntryPassTemplate() {
  templateLoading.value = true;
  try {
    const settingsData: any = await _getEntryPassSettings(siteId);
    const template = settingsData?.data?.settings?.template;
    entryPassTemplate.value = template?.id ? template : { id: "", name: "" };
  } catch {
    entryPassTemplate.value = { id: "", name: "" };
  } finally {
    templateLoading.value = false;
  }
}

watch(uploadMode, (mode) => {
  if (mode === "bulk") fetchEntryPassTemplate();
});

onMounted(async () => {
  try {
    const { encrypted: acmUrl } = await $fetch<{ encrypted: string }>(
      "/api/encrypt-acm-url"
    );
    encryptedAcmUrl.value = acmUrl;
    const [doorLevels, liftLevels, groups] = await Promise.all([
      _getDoorAccessLevels(acmUrl),
      _getLiftAccessLevels(acmUrl),
      _getAccessGroups(acmUrl),
    ]);
    accessLevelItems.value = doorLevels.data ?? [];
    liftAccessLevelItems.value = liftLevels.data ?? [];
    accessGroupItems.value = groups.data ?? [];
  } catch (error) {
    console.error("Failed to fetch access management data:", error);
    emit("error", "EntryPass server is unavailable. Please contact your administrator.");
  }
});

function limitCardNumber() {
  if (card.value.cardNumber && card.value.cardNumber.toString().length > cardNoMaxLength.value) {
    card.value.cardNumber = card.value.cardNumber.toString().slice(0, cardNoMaxLength.value);
  }
}

function limitPinNo() {
  if (card.value.pinNo && card.value.pinNo.toString().length > cardPinMaxLength.value) {
    card.value.pinNo = card.value.pinNo.toString().slice(0, cardPinMaxLength.value);
  }
}

function enforceMinQuantity() {
  if (card.value.quantity < 1 || !card.value.quantity) {
    card.value.quantity = 1;
  }
}

function updateEndDate(startDate: string | null) {
  if (startDate) {
    const date = new Date(startDate);
    date.setFullYear(date.getFullYear() + 10);
    card.value.endDate = formatDate(date);
  }
}

// Watch for Assign toggle to fetch block/level/unit data
watch(() => card.value.showAssign, async (newVal) => {
  if (newVal) {
    try {
      const response = await _getBlockLevelUnitList(siteId);
      blockLevelUnitData.value = (response as any)?.data || [];
      buildingItems.value = blockLevelUnitData.value.map((b: any) => ({
        name: b.block,
        value: b._id,
      }));
    } catch (error) {
      console.error("Failed to fetch block/level/unit list:", error);
    }
  } else {
    card.value.assignBuilding = "";
    card.value.assignLevel = "";
    card.value.assignUnit = "";
    blockLevelUnitData.value = [];
    buildingItems.value = [];
    levelItems.value = [];
    unitItems.value = [];
  }
});

// Watch for building selection to populate levels
watch(() => card.value.assignBuilding, (newVal) => {
  card.value.assignLevel = "";
  card.value.assignUnit = "";
  unitItems.value = [];

  if (newVal) {
    const selectedBlock = blockLevelUnitData.value.find((b: any) => b._id === newVal);
    levelItems.value = selectedBlock?.levels?.map((l: any) => ({
      name: l.level,
      value: l._id,
    })) || [];
  } else {
    levelItems.value = [];
  }
});

// Watch for level selection to populate units
watch(() => card.value.assignLevel, (newVal) => {
  card.value.assignUnit = "";

  if (newVal && card.value.assignBuilding) {
    const selectedBlock = blockLevelUnitData.value.find((b: any) => b._id === card.value.assignBuilding);
    const selectedLevel = selectedBlock?.levels?.find((l: any) => l._id === newVal);
    unitItems.value = selectedLevel?.units?.map((u: any) => ({
      name: u.name,
      value: u._id,
    })) || [];
  } else {
    unitItems.value = [];
  }
});

function cancel() {
  //   createMore.value = false;
  message.value = "";
  emit("cancel");
}

function buildPhysicalCardPayload() {
  const now = new Date().toISOString();
  const doorItem = accessLevelItems.value.find((i: any) => i.no === card.value.door);
  const liftItem = liftAccessLevelItems.value.find((i: any) => i.no === card.value.liftAccessLevel);

  return {
    site: siteId,
    cardNo: card.value.cardNumber,
    isActivated: card.value.isActivate,
    isAntiPassBack: card.value.isAntiPassBack,
    isLiftCard: card.value.useAsLiftCard,
    userType: "Visitor/Resident",
    accessLevel: card.value.door,
    accessGroup: card.value.accessGroup,
    accessType: card.value.cardType,
    startDate: card.value.startDate,
    endDate: card.value.endDate,
    doorName: doorItem?.name ?? "",
    createdAt: now,
    updatedAt: now,
    ...(card.value.pinNo ? { pin: card.value.pinNo } : {}),
    ...(card.value.useAsLiftCard
      ? {
          liftAccessLevel: card.value.liftAccessLevel,
          liftName: liftItem?.name ?? "",
        }
      : {}),
    ...(card.value.assignUnit ? { unit: [card.value.assignUnit] } : {}),
    ...(card.value.isWinsland !== undefined ? { isWinsland: card.value.isWinsland } : {}),
  };
}

function buildNonPhysicalCardPayload() {
  const now = new Date().toISOString();
  const doorItem = accessLevelItems.value.find((i: any) => i.no === card.value.door);
  const liftItem = liftAccessLevelItems.value.find((i: any) => i.no === card.value.liftAccessLevel);

  return {
    site: siteId,
    quantity: card.value.quantity,
    accessLevel: card.value.door,
    isLiftCard: card.value.useAsLiftCard,
    accessGroup: card.value.accessGroup,
    userType: "Visitor/Resident",
    doorName: doorItem?.name ?? "",
    startDate: card.value.startDate,
    endDate: card.value.endDate,
    createdAt: now,
    updatedAt: now,
    ...(card.value.useAsLiftCard
      ? {
          liftAccessLevel: card.value.liftAccessLevel,
          liftName: liftItem?.name ?? "",
        }
      : {}),
    ...(card.value.assignUnit ? { unit: [card.value.assignUnit] } : {}),
    ...(card.value.isWinsland !== undefined ? { isWinsland: card.value.isWinsland } : {}),
  };
}

async function downloadBulkTemplate() {
  const { id, name } = entryPassTemplate.value;
  try {
    const response = await fetch(getFileUrl(id));
    const blob = await response.blob();
    const blobUrl = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = blobUrl;
    link.download = name || "access-card-template";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(blobUrl);
  } catch {
    console.error("Failed to download template");
  }
}

async function submit() {
  disable.value = true;
  try {
    if (uploadMode.value === "bulk") {
      await _bulkPhysicalAccessCard({ site: siteId, file: bulkFile.value! });
      emit("success");
      return;
    }

    if (prop.mode === "add") {
      if (isNonPhysicalCard.value) {
        await _addNonPhysicalCard(buildNonPhysicalCardPayload());
      } else {
        await _addPhysicalCard(buildPhysicalCardPayload());
      }
    }

    if (prop.mode === "edit") {
      await _updateCardById(prop.card._id ?? "", { ...card.value });
    }
    emit("success");
  } catch (error: any) {
    const msg = error.response?._data?.message || error?.data?.message || "An error occurred. Please try again.";
    emit("error", msg);
  } finally {
    disable.value = false;
  }
}
</script>
