<script setup>
import PageTitle from "@/components/global/PageTitle.vue";
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
import { SessionUser } from "@/components/session/token/SessionUser.vue";
import DepartmentSubPageWrapper from "@/views/dashboards/superUserDashboard/department/DepartmentSubPageWrapper.vue";
import { departmentAdvanced, setDepartment, departmentId } from "@/views/dashboards/superUserDashboard/department/SuperUserSelectedDepartmentObject.vue";
import { useRouter } from "vue-router";
import { computed, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import ConfigurationSelect from "@/components/displays/superuser/configuration/ConfigurationSelect.vue";
import SuperuserOverviewPanel from "@/components/displays/superuser/overview/SuperuserOverviewPanel.vue";
import SuperUserDashboardDepartmentModulesNavigation
  from "@/views/dashboards/superUserDashboard/department/modules/SuperUserDashboardDepartmentModulesNavigation.vue";
import ConfigurationSwitch from "@/components/displays/superuser/configuration/ConfigurationSwitch.vue";
import ConfigurationInput from "@/components/displays/superuser/configuration/ConfigurationInput.vue";
import {
  getDepartmentSelfServeStatus,
  setDepartmentSelfServeStatus,
} from "@/composables/departmentSelfServeEnabled.js";

// Get the department from the route
const router = useRouter();
const { t } = useI18n({ useScope: "global" });
const departmentTitle = computed(() => departmentAdvanced.value.name || t("superuser_dashboard.department_navigation.modules"));
const pageSubtitle = computed(() => t("superuser_dashboard.department_pages.modules.subtitle"));

const departmentVariables = ref([]);
const workfeedDepartmentOptions = ref([{ value: "", label: "No Workfeed department" }]);
const isLoadingWorkfeedDepartments = ref(false);
const workfeedDepartmentOptionsError = ref("");
const selfServeEnabled = ref(false);
const selfServeAutoDeactivation = ref({ at: null, timezone: "Europe/Copenhagen", label: "NEVER" });
const isLoadingSelfServeEnabled = ref(false);
const isSavingSelfServeEnabled = ref(false);
const selfServeEnabledError = ref("");
let departmentVariablesRequestSequence = 0;
let selfServeStatusRequestSequence = 0;
let selfServeSaveRequestSequence = 0;
const departmentVariableDescriptions = computed(() => ({
  bookingsystem_enabled: t("superuser_dashboard.department_pages.modules.variables.bookingsystem_enabled"),
  bookingsystem_time_based_enabled: t("superuser_dashboard.department_pages.modules.variables.bookingsystem_time_based_enabled"),
  bookingsystem_time_based_password: t("superuser_dashboard.department_pages.modules.variables.bookingsystem_time_based_password"),
  exclude_from_invoicing: t("superuser_dashboard.department_pages.modules.variables.exclude_from_invoicing"),
  workfeed_department_id: t("superuser_dashboard.department_pages.modules.variables.workfeed_department_id"),
}));

const departmentVariableRows = computed(() => departmentVariables.value.map((variable) => ({
  key: `${variable.variable}:${variable.id}`,
  label: departmentVariableDescriptions.value[variable.variable] || variable.variable,
  value: variable.value,
})));

const selfServeAutoDeactivationText = computed(() => {
  if (!selfServeEnabled.value) {
    return "Automatic deactivation: not scheduled while self-serve is disabled.";
  }

  const label = String(selfServeAutoDeactivation.value?.label || "").trim();
  return `Automatic deactivation: ${label || "NEVER"}`;
});

const getDepartmentVariables = async (
  requestedDepartmentId = String(departmentId.value)
) => {
  const requestSequence = ++departmentVariablesRequestSequence;
  try {
    const response = await SessionUser.request(
      SessionUser.objects.department_variables.meta.endpoint,
      "GET",
      {
        filters: "department_id:" + requestedDepartmentId,
      }
    );
    if (
      requestSequence !== departmentVariablesRequestSequence
      || String(departmentId.value) !== requestedDepartmentId
    ) {
      return false;
    }
    departmentVariables.value = response.data.data;
    return true;
  } catch (error) {
    if (
      requestSequence === departmentVariablesRequestSequence
      && String(departmentId.value) === requestedDepartmentId
    ) {
      console.log(error);
    }
    return false;
  }
};

const getVariableValue = (variable) => {
  if (departmentVariables.value.length === 0) {
    return null;
  }
  // Find the variable in the department variables
  const configuredVariable = departmentVariables.value.find((item) => item.variable === variable);
  // If the variable is found, return the value
  if (configuredVariable) {
    return configuredVariable;
  }
  // If the variable is not found, return null
  return null;
};

const getVariableStringValue = (variable) => {
  const configuredVariable = getVariableValue(variable);
  if (!configuredVariable || configuredVariable.value === undefined || configuredVariable.value === null) {
    return "";
  }
  return String(configuredVariable.value);
};

const getBooleanValue = (variable) => {
  if (departmentVariables.value.length === 0) {
    return false;
  }
  // Find the variable in the department variables
  if (getVariableValue(variable)) {
    // If the variable is found, return the value
    return getVariableValue(variable).value === "true";
  }
  return false;
};

const getWorkfeedItems = (payload) => {
  if (Array.isArray(payload?.items)) {
    return payload.items;
  }
  if (Array.isArray(payload?.results)) {
    return payload.results;
  }
  if (Array.isArray(payload)) {
    return payload;
  }
  return [];
};

const getWorkfeedDepartmentOptions = async () => {
  isLoadingWorkfeedDepartments.value = true;
  workfeedDepartmentOptionsError.value = "";
  try {
    const response = await SessionUser.superUser.modules.workfeed.functions.listDepartments();
    const departments = getWorkfeedItems(response?.data?.data);
    const options = departments
      .map((workfeedDepartment) => {
        const mappedDepartmentId = String(workfeedDepartment?.id ?? "").trim();
        if (!mappedDepartmentId) {
          return null;
        }
        const mappedDepartmentName = String(workfeedDepartment?.name ?? "").trim();
        return {
          value: mappedDepartmentId,
          label: mappedDepartmentName || mappedDepartmentId,
        };
      })
      .filter((option) => option !== null);

    workfeedDepartmentOptions.value = [
      { value: "", label: "No Workfeed department" },
      ...options,
    ];
  } catch (error) {
    console.log(error);
    workfeedDepartmentOptionsError.value = "Unable to load Workfeed departments.";
    workfeedDepartmentOptions.value = [{ value: "", label: "No Workfeed department" }];
  } finally {
    isLoadingWorkfeedDepartments.value = false;
  }
};

const setWorkfeedDepartmentId = async (selectedDepartmentId) => {
  await SessionUser.objects.department_variables.add(
    departmentId.value,
    "workfeed_department_id",
    selectedDepartmentId ?? ""
  ).then(() => {
    getDepartmentVariables();
  });
};

const loadSelfServeEnabled = async ({
  preserveEnabledOnError = false,
  requestedDepartmentId = String(departmentId.value),
} = {}) => {
  const requestSequence = ++selfServeStatusRequestSequence;
  isLoadingSelfServeEnabled.value = true;
  selfServeEnabledError.value = "";
  try {
    const status = await getDepartmentSelfServeStatus(requestedDepartmentId);
    if (
      requestSequence !== selfServeStatusRequestSequence
      || String(departmentId.value) !== requestedDepartmentId
    ) {
      return false;
    }
    selfServeEnabled.value = status.enabled;
    selfServeAutoDeactivation.value = status.autoDeactivation;
    return true;
  } catch (error) {
    console.log(error);
    if (
      requestSequence === selfServeStatusRequestSequence
      && String(departmentId.value) === requestedDepartmentId
    ) {
      selfServeEnabledError.value = "Unable to load self-serve status.";
      if (!preserveEnabledOnError) {
        selfServeEnabled.value = false;
      }
    }
    return false;
  } finally {
    if (requestSequence === selfServeStatusRequestSequence) {
      isLoadingSelfServeEnabled.value = false;
    }
  }
};

const updateSelfServeEnabled = async (enabled) => {
  const requestedDepartmentId = String(departmentId.value);
  const requestSequence = ++selfServeSaveRequestSequence;
  const previousValue = selfServeEnabled.value;
  selfServeEnabled.value = Boolean(enabled);
  isSavingSelfServeEnabled.value = true;
  selfServeEnabledError.value = "";

  try {
    const status = await setDepartmentSelfServeStatus(requestedDepartmentId, enabled);
    if (
      requestSequence !== selfServeSaveRequestSequence
      || String(departmentId.value) !== requestedDepartmentId
    ) {
      return;
    }
    selfServeEnabled.value = status.enabled;
    if (status.hasAutoDeactivation) {
      selfServeAutoDeactivation.value = status.autoDeactivation;
    } else {
      await loadSelfServeEnabled({
        preserveEnabledOnError: true,
        requestedDepartmentId,
      });
    }
  } catch (error) {
    console.log(error);
    if (
      requestSequence === selfServeSaveRequestSequence
      && String(departmentId.value) === requestedDepartmentId
    ) {
      selfServeEnabled.value = previousValue;
      selfServeEnabledError.value = "Unable to update self-serve status.";
    }
  } finally {
    if (
      requestSequence === selfServeSaveRequestSequence
      && String(departmentId.value) === requestedDepartmentId
    ) {
      isSavingSelfServeEnabled.value = false;
    }
  }
};

getWorkfeedDepartmentOptions();
watch(
  () => router.currentRoute.value.params.departmentId,
  (nextDepartmentId) => {
    selfServeSaveRequestSequence++;
    isSavingSelfServeEnabled.value = false;
    setDepartment(nextDepartmentId);
    departmentVariables.value = [];
    selfServeEnabled.value = false;
    selfServeAutoDeactivation.value = {
      at: null,
      timezone: "Europe/Copenhagen",
      label: "NEVER",
    };
    selfServeEnabledError.value = "";
    getDepartmentVariables(String(nextDepartmentId));
    loadSelfServeEnabled();
  },
  { immediate: true }
);
</script>

<template>
  <RestrictedPageWrapper :hasPermission="SessionUser.canAccessSuperUser()">
    <DepartmentSubPageWrapper>
      <template #title>
        <PageTitle :title="departmentTitle" :subtitle="pageSubtitle" />
      </template>
      <div class="department-modules">
        <SuperUserDashboardDepartmentModulesNavigation />
        <SuperuserOverviewPanel
          :title="$t('objects.columns.value')"
          :subtitle="$t('superuser_dashboard.department_pages.modules.subtitle')"
          data-testid="department-module-variables"
        >
          <div v-if="departmentVariableRows.length === 0" class="has-text-grey">
            {{ $t('common.none') }}
          </div>
          <dl v-else class="department-modules-variables">
            <div v-for="row in departmentVariableRows" :key="row.key" class="department-modules-variables__row">
              <dt>{{ row.label }}</dt>
              <dd>{{ row.value || $t('common.none') }}</dd>
            </div>
          </dl>
        </SuperuserOverviewPanel>
        <SuperuserOverviewPanel
          :title="$t('superuser_dashboard.department_navigation.modules')"
          :subtitle="$t('superuser_dashboard.department_pages.modules.subtitle')"
        >
          <template #default>
            <ConfigurationSwitch
              title="Bookingsystem (ikke tidsbaseret)"
              description="Aktiver bookingsystem"
              v-bind:value="getBooleanValue('bookingsystem_enabled')"
              :on-switch="(value) => {
                SessionUser.objects.department_variables.add(
                  departmentId,
                  'bookingsystem_enabled',
                  value ? 'true' : 'false'
                ).then(() => {
                  getDepartmentVariables();
                });
              }"
            ></ConfigurationSwitch>
            <ConfigurationSwitch
              title="Bookingsystem (tidsbaseret)"
              description="Aktiver bookingsystem"
              v-bind:value="getBooleanValue('bookingsystem_time_based_enabled')"
              :on-switch="(value) => {
                SessionUser.objects.department_variables.add(
                  departmentId,
                  'bookingsystem_time_based_enabled',
                  value ? 'true' : 'false'
                ).then(() => {
                  getDepartmentVariables();
                });
              }"
            ></ConfigurationSwitch>
            <ConfigurationInput
              title="Booking system (tidsbaseret) kodeord"
              description="Kodeord til booking system (tidsbaseret)"
              v-bind:value="getVariableValue('bookingsystem_time_based_password')"
              :on-save="(value) => {
                SessionUser.objects.department_variables.add(
                  departmentId,
                  'bookingsystem_time_based_password',
                  value
                ).then(() => {
                  getDepartmentVariables();
                });
              }"
            ></ConfigurationInput>
          </template>
        </SuperuserOverviewPanel>
        <SuperuserOverviewPanel
          title="Invoicing"
          :subtitle="$t('superuser_dashboard.department_pages.modules.variables.exclude_from_invoicing')"
        >
          <template #default>
            <ConfigurationSwitch
              title="Udeluk fra fakturering"
              description="If enabled, this department is excluded from invoicing. Changes can take up to 5 minutes."
              v-bind:value="getBooleanValue('exclude_from_invoicing')"
              :on-switch="(value) => {
                SessionUser.objects.department_variables.add(
                  departmentId,
                  'exclude_from_invoicing',
                  value ? 'true' : 'false'
                ).then(() => {
                  getDepartmentVariables();
                });
              }"
            ></ConfigurationSwitch>
          </template>
        </SuperuserOverviewPanel>
        <SuperuserOverviewPanel
          title="Self-serve"
          :subtitle="$t('superuser_dashboard.department_pages.modules.subtitle')"
        >
          <template #default>
            <div :title="selfServeAutoDeactivationText">
              <ConfigurationSwitch
                title="Selvvask"
                :description="selfServeAutoDeactivationText"
                :value="selfServeEnabled"
                :disabled="isLoadingSelfServeEnabled || isSavingSelfServeEnabled"
                :on-switch="updateSelfServeEnabled"
              ></ConfigurationSwitch>
            </div>
            <p class="help is-danger" v-if="selfServeEnabledError">
              {{ selfServeEnabledError }}
            </p>
          </template>
        </SuperuserOverviewPanel>
        <SuperuserOverviewPanel
          title="Workfeed"
          :subtitle="$t('superuser_dashboard.department_pages.modules.variables.workfeed_department_id')"
        >
          <template #default>
            <ConfigurationSelect
              label="Workfeed department"
              description="Select the Workfeed department that this local department should map to."
              :options="workfeedDepartmentOptions"
              :on-select="setWorkfeedDepartmentId"
              :value="getVariableStringValue('workfeed_department_id')"
              :disabled="isLoadingWorkfeedDepartments"
              :icon="'fas fa-building'"
            ></ConfigurationSelect>
            <p class="help is-danger" v-if="workfeedDepartmentOptionsError">
              {{ workfeedDepartmentOptionsError }}
            </p>
          </template>
        </SuperuserOverviewPanel>
      </div>
    </DepartmentSubPageWrapper>
  </RestrictedPageWrapper>
</template>

<style scoped>
.department-modules {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
</style>
