<template>
  <q-page class="dashboard-page bg-page">
    <template v-if="loading">
      <div
        class="bg-surface full-width items-center justify-center row"
        style="height: 80vh"
      >
        <q-spinner-dots color="primary" />
      </div>
    </template>

    <template v-else>
      <q-pull-to-refresh color="primary" @refresh="onRefresh">
        <DashboardHeaderBar :data="headerBar" :notifications="notifications" />

        <DashboardSummaryInfos :data="summaryInfos" />

        <DashboardPendingApproval v-if="isPendingProvider" />

        <template v-else>
          <DashboardPriceSuggest :data="priceSuggestion" />

          <DashboardTodayServices
            v-if="todayServices?.length > 0"
            :data="todayServices"
            @refresh="loadDashboard"
            @rate="openRatingDialog"
          />

          <DashboardScrollAreaSchedules />

          <DashboardSolicitations
            v-if="solicitations?.length > 0"
            :data="solicitations"
            @accept="(item) => openDetailsDialog(item)"
            @reject="(item) => openDetailsDialog(item, 'confirm-reject')"
            @view-details="(item) => openDetailsDialog(item)"
          />

          <DashboardPendingConfirmation
            v-if="pendingConfirmation.length > 0"
            :data="pendingConfirmation"
            @view-details="(item) => openNextScheduleDialog(item)"
          />

          <DashboardNextSchedules
            :data="nextSchedules"
            @view-details="(item) => openNextScheduleDialog(item)"
          />

          <DashboardOpportunities :data="opportunities" />
        </template>
      </q-pull-to-refresh>
    </template>
  </q-page>
</template>

<script setup>
import { dadosDashboard } from "src/api/dashboard";
import { onMounted, onUnmounted, ref, watch } from "vue";
import { acceptServicePackage, rejectServicePackage, updateScheduleStatus } from "src/api/schedule";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
import { useAuth } from "src/composables/useAuth";
import { useProviderApproval } from "src/composables/useProviderApproval";
import { useRoute, useRouter } from "vue-router";

import DashboardHeaderBar from "src/components/dashboard/DashboardHeaderBar.vue";
import DashboardNextSchedules from "src/components/dashboard/DashboardNextSchedules.vue";
import DashboardOpportunities from "src/components/dashboard/DashboardOpportunities.vue";
import DashboardPendingApproval from "src/components/dashboard/DashboardPendingApproval.vue";
import DashboardPriceSuggest from "src/components/dashboard/DashboardPriceSuggest.vue";
import DashboardScrollAreaSchedules from "src/components/dashboard/DashboardScrollAreaSchedules.vue";
import DashboardSolicitations from "src/components/dashboard/DashboardSolicitations.vue";
import DashboardSummaryInfos from "src/components/dashboard/DashboardSummaryInfos.vue";
import DashboardTodayServices from "src/components/dashboard/DashboardTodayServices.vue";
import NextSchedulesDetailsDialog from "src/components/dashboard/NextSchedulesDetailsDialog.vue";
import ScheduleRatingDialog from "src/components/dashboard/ScheduleRatingDialog.vue";
import SolicitationDetailsDialog from "src/components/dashboard/SolicitationDetailsDialog.vue";
import ProposalAcceptedDialog from "src/components/dashboard/ProposalAcceptedDialog.vue";
import OpportunityDialog from "src/pages/opportunities/components/OpportunityDialog.vue";
import DashboardPendingConfirmation from "src/components/dashboard/DashboardPendingConfirmation.vue";

const $q = useQuasar();
const router = useRouter();
const route = useRoute();
const { t } = useI18n();
const { refreshApprovalStatus } = useAuth();
const { isPendingProvider } = useProviderApproval();

// Enquanto o cadastro está em análise, reconsulta a aprovação periodicamente
// para liberar a dashboard completa sem exigir novo login.
const APPROVAL_POLL_INTERVAL_MS = 3 * 60 * 1000;

let approvalPollId = null;

const headerBar = ref({});
const loading = ref(true);
const nextSchedules = ref([]);
const notifications = ref([]);
const opportunities = ref([]);
const priceSuggestion = ref({});
const solicitations = ref([]);
const summaryInfos = ref({});
const todayServices = ref([]);
const pendingConfirmation = ref([]);

const handleScheduleAction = async (id, status, ids = [], servicePackageId = null) => {
  try {
    if (servicePackageId && status === "accepted") {
      await acceptServicePackage(servicePackageId);
    } else if (servicePackageId && status === "rejected") {
      await rejectServicePackage(servicePackageId);
    } else {
      const scheduleIds = ids.length ? ids : [id];

      await Promise.all(
        scheduleIds.map((scheduleId) => updateScheduleStatus(scheduleId, status)),
      );
    }
  } catch (e) {
    console.log(e);
  } finally {
    await loadDashboard();
  }
};

const loadDashboard = async () => {
  const response = await dadosDashboard();

  if (response) {
    headerBar.value = response.headerBar;
    nextSchedules.value = response.nextSchedules ?? [];
    notifications.value = response.notifications ?? [];
    opportunities.value = response.opportunities ?? [];
    priceSuggestion.value = response.priceSuggested;
    solicitations.value = response.solicitations ?? [];
    summaryInfos.value = response.summaryInfos;
    pendingConfirmation.value = response.pendingConfirmation ?? [];
    todayServices.value = response.todayServices ?? [];
  }
};

const checkApprovalStatus = async () => {
  if (!isPendingProvider.value) {
    return false;
  }

  try {
    const approved = await refreshApprovalStatus();

    if (!approved) {
      return false;
    }

    stopApprovalPolling();

    $q.notify({
      message: t("provider.dashboard.pending_approval.approved"),
      type: "positive",
    });

    await loadDashboard();

    return true;
  } catch (error) {
    console.error(error);

    return false;
  }
};

const startApprovalPolling = () => {
  if (approvalPollId || !isPendingProvider.value) {
    return;
  }

  approvalPollId = setInterval(checkApprovalStatus, APPROVAL_POLL_INTERVAL_MS);
};

const stopApprovalPolling = () => {
  if (!approvalPollId) {
    return;
  }

  clearInterval(approvalPollId);

  approvalPollId = null;
};

const onRefresh = async (done) => {
  try {
    const approved = await checkApprovalStatus();

    if (!approved) {
      await loadDashboard();
    }
  } finally {
    done();
  }
};

const openDetailsDialog = (solicitation, initialView = "details") => {
  $q.dialog({
    component: SolicitationDetailsDialog,
    componentProps: { initialView, solicitation },
  }).onOk(async ({ action, id, ids, service_package_id }) => {
  await handleScheduleAction(
    id,
    action === "accept" ? "accepted" : "rejected",
    ids,
    service_package_id,
  );

  if (action === "accept") {
    $q.dialog({
      component: ProposalAcceptedDialog,
    });
  }
});
};

const openNextScheduleDialog = (schedule) => {
  $q.dialog({
    component: NextSchedulesDetailsDialog,
    componentProps: { schedule },
  }).onOk(async ({ action }) => {
    if (action === "cancelled") {
      await loadDashboard();
    }
  });
};

const openRatingDialog = (schedule) => {
  $q.dialog({
    component: ScheduleRatingDialog,
    componentProps: { schedule },
  }).onOk(() => {
    loadDashboard();
  });
};

// Chegada pela push de cadastro aprovado: o status já foi revalidado no boot,
// aqui só recarregamos a dashboard liberada e avisamos o prestador.
watch(
  () => route.query.approved,
  async (val) => {
    if (val !== "true") {
      return;
    }

    stopApprovalPolling();

    if (!loading.value) {
      await loadDashboard();
    }

    $q.notify({
      message: t("provider.dashboard.pending_approval.approved"),
      type: "positive",
    });

    router.replace({ path: route.path, query: {} });
  },
  { immediate: true },
);

watch(
  () => route.query.showSuccessModal,
  async (val) => {
    if (val === "true") {
      if (!loading.value) {
        await loadDashboard();
      }

      $q.dialog({ component: OpportunityDialog }).onDismiss(() => {
        router.replace({ path: route.path, query: {} });
      });
    }
  },
  { immediate: true },
);

onMounted(async () => {
  await loadDashboard();
  loading.value = false;

  startApprovalPolling();
});

onUnmounted(() => {
  stopApprovalPolling();
});
</script>

<style scoped>
.dashboard-page {
  box-sizing: border-box;
  min-height: 100%;
  width: 100%;
}
</style>
