<template>
  <v-row no-gutters align="center" justify="center">
    <v-col cols="12" lg="12">
      <TableMain
        v-if="canViewSchedules"
        :title="'Cleaner Checklist'"
        :items="items"
        :headers="headers"
        :loading="loading"
        :show-header="true"
        v-model:page="page"
        :pages="pages"
        :pageRange="pageRange"
        :no-data-text="'No Cleaner Checklist found'"
        @refresh="getCleanerChecklistRefresh"
        @row-click="onRowClick"
      >
        <template #extension>
          <v-row no-gutters class="w-100 d-flex flex-column">
            <v-card
              class="w-100 px-3 d-flex align-center ga-5 py-2"
              flat
              :height="60"
            >
              <InputDateTimePicker
                v-model:utc="startDate"
                density="compact"
                hide-details
              />
              <InputDateTimePicker
                v-model:utc="endDate"
                density="compact"
                hide-details
              />
              <v-select
                v-model="status"
                :items="statusOptions"
                density="compact"
                hide-details
                class="mx-3"
                style="max-width: 160px"
                item-title="title"
                item-value="value"
                label="Status"
              />
            </v-card>
          </v-row>
        </template>

        <template #item.createdAt="{ value }">
          {{
            formatDate
              ? formatDate(value)
              : value
              ? new Date(value).toLocaleString()
              : ""
          }}
        </template>
        <template #item.closeIn="{ item }">
          <v-chip
            class="text-capitalize"
            variant="flat"
            :color="getCloseInColor(item._id)"
            pill
          >
            {{ remainingTime[item._id] || "00h 00m" }}
          </v-chip>
        </template>
        <template #item.status="{ value }">
          <v-chip
            class="text-capitalize"
            :color="getStatusColor(value)"
            variant="flat"
            pill
          >
            {{ value || "No Status" }}
          </v-chip>
        </template>
        <template #item.completedAt="{ value }">
          {{
            formatDate
              ? formatDate(value)
              : value
              ? new Date(value).toLocaleString()
              : ""
          }}
        </template>
        <template #item.download="{ item }">
          <v-btn
            v-if="canDownloadSchedule"
            variant="outlined"
            size="medium"
            class="text-capitalize px-4 py-2"
            :loading="downloadingId === item._id"
            @click.stop="downloadItem(item)"
          >
            <v-icon left>mdi-download</v-icon>
            Download
          </v-btn>
        </template>
      </TableMain>
      <div v-else class="pa-4">
        <v-card variant="outlined" class="pa-4">
          <div class="text-subtitle-1">
            You do not have permission to view cleaning schedules.
          </div>
        </v-card>
      </div>
    </v-col>
  </v-row>
</template>

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

const props = defineProps({
  orgId: { type: String, required: true },
  site: { type: String, required: true },
  type: { type: String, required: true },
  serviceType: { type: String, default: "" },
  scheduleRoute: { type: String, default: "cleaning-schedule" },
  canViewSchedules: { type: Boolean, default: true },
  canViewScheduleDetails: { type: Boolean, default: true },
  canDownloadSchedule: { type: Boolean, default: false },
  canManageScheduleTasks: { type: Boolean, default: false },
});

const startDate = ref("");
const endDate = ref("");
const status = ref<TScheduleAreaStatus>("all");
const statusOptions = [
  { title: "All", value: "all" },
  { title: "Open", value: "open" },
  { title: "Ongoing", value: "ongoing" },
  { title: "Completed", value: "completed" },
] as const;

const items = ref<Array<Record<string, any>>>([]);
const page = ref(1);
const pages = ref(0);
const pageRange = ref("-- - -- of --");

const headers = [
  { title: "Created Date", value: "createdAt" },
  { title: "Close in", value: "closeIn" },
  { title: "Status", value: "status" },
  { title: "Completion Date", value: "completedAt" },
  { title: "", value: "download" },
];
const remainingTime = ref({} as Record<string, string>);
const remainingSeconds = ref({} as Record<string, number>);
const downloadingId = ref<string | null>(null);

const { getCleaningSchedules, downloadChecklistPdf } = useCleaningSchedules();
const { formatDate } = useUtils();

const getStatusColor = (status: unknown): string => {
  if (!status) return "grey";

  const normalized = String(status).toLowerCase();

  switch (normalized) {
    case "open":
      return "grey";
    case "ongoing":
      return "primary";
    case "completed":
    case "accepted":
      return "success";
    case "closed":
    case "rejected":
      return "error";
    default:
      return "secondary";
  }
};

const getCloseInColor = (id: string): string => {
  const secs = remainingSeconds.value[id];
  if (secs === undefined) return "primary";
  if (secs <= 0) return "error";
  if (secs < 3 * 3600) return "warning";
  return "primary";
};

const canDownloadSchedule = computed(() => props.canDownloadSchedule);
const canViewSchedules = computed(() => props.canViewSchedules);
const canViewScheduleDetails = computed(() => props.canViewScheduleDetails);
const canManageScheduleTasks = computed(() => props.canManageScheduleTasks);

const {
  data: getCleanerChecklistReq,
  refresh: getCleanerChecklistRefresh,
  pending: loading,
} = await useLazyAsyncData(
  "get-all-areas",
  () =>
    getCleaningSchedules({
      page: page.value,
      site: props.site,
      startDate: startDate.value,
      endDate: endDate.value,
      status: status.value === "all" ? undefined : status.value,
      serviceType: props.serviceType,
    }),
  {
    watch: [() => page.value, () => props.site, startDate, endDate, status],
  }
);

function calculateRemainingTime(
  closeIn: Date | string | number | null | undefined
) {
  if (!closeIn) return -1;
  const _date = new Date(closeIn);
  if (isNaN(_date.getTime())) return -1;
  const remainingMs = _date.getTime() - Date.now();
  return Math.floor(remainingMs / 1000);
}

const formatTime = (seconds: number) => {
  if (seconds <= 0 || isNaN(seconds)) return "00h 00m";
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  return `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(
    2,
    "0"
  )}m`;
};

const updateRemainingTime = () => {
  items.value.forEach((item) => {
    const itemId = item._id as string;
    const _time = calculateRemainingTime(item.closeIn as string);
    remainingSeconds.value[itemId] = _time;
    remainingTime.value[itemId] = _time <= 0 ? "00h 00m" : formatTime(_time);
  });
};

watchEffect(() => {
  if (getCleanerChecklistReq.value) {
    items.value = getCleanerChecklistReq.value.items;
    pages.value = getCleanerChecklistReq.value.pages;
    pageRange.value = getCleanerChecklistReq.value.pageRange;
  }

  updateRemainingTime();
});

let _countdownInterval: ReturnType<typeof setInterval> | null = null;

onMounted(() => {
  _countdownInterval = setInterval(updateRemainingTime, 60_000);

  try {
    const { $socket } = useNuxtApp() as any;
    if ($socket) {
      $socket.emit("join:cleaning-schedule", props.site);

      $socket.on("cleaning-schedule:updated", (payload: { siteId: string }) => {
        if (payload?.siteId !== props.site) return;
        getCleanerChecklistRefresh();
      });

      $socket.on("cleaning-schedule:expired", () => {
        getCleanerChecklistRefresh();
      });
    }
  } catch (_) {}
});

onUnmounted(() => {
  if (_countdownInterval) clearInterval(_countdownInterval);

  try {
    const { $socket } = useNuxtApp() as any;
    if ($socket) {
      $socket.emit("leave:cleaning-schedule", props.site);
      $socket.off("cleaning-schedule:updated");
      $socket.off("cleaning-schedule:expired");
    }
  } catch (_) {}
});

async function downloadItem(item: any) {
  const id = item?._id;
  if (!id) return;

  try {
    downloadingId.value = id;
    await downloadChecklistPdf(id);
  } catch (err) {
    console.error("Failed to download checklist PDF", err);
  } finally {
    downloadingId.value = null;
  }
}

const selectedScheduleStatus = useState<string>(
  "selectedScheduleStatus",
  () => ""
);

const isItemClosed = (item: any): boolean =>
  String(item?.status ?? "").toLowerCase() === "closed";

function onRowClick(data: any) {
  const item = data?.item ?? data;
  const id = item?._id || item?.id || item?.areaId;
  if (id) {
    if (!canViewScheduleDetails.value) {
      showMessage(
        "You do not have permission to view schedule details.",
        "error"
      );
      return;
    }

    // Store status so nested pages know whether the schedule is closed
    selectedScheduleStatus.value = String(item?.status ?? "");

    if (props.type === "toilet") {
      const path = `/${props.orgId}/${props.site}/toilet-checklist/${id}`;
      navigateTo(path);
      return;
    }
    const path = `/${props.orgId}/${props.site}/${props.scheduleRoute}/${id}`;
    navigateTo(path);
  } else {
    console.warn("Row clicked but no id found to navigate:", item);
  }
}

function showMessage(msg: string, color: string = "error") {
  try {
    console.warn(msg);
  } catch (e) {
    alert(msg);
  }
}
</script>
