<script setup>
import { computed, ref, watch } from "vue";
import Dropdown from "primevue/dropdown";
import InputNumber from "primevue/inputnumber";
import BaseButton from "../../../components/base/BaseButton.vue";
import BaseInputText from "../../../components/base/BaseInputText.vue";
import { fetchTasks } from "../composables/useHoursApi.js";
import { useHoursTimer } from "../composables/useHoursTimer.js";
import strings from "../strings.js";

const props = defineProps({
  weekLocked: { type: Boolean, default: false },
  hasInternalCategories: { type: Boolean, default: false },
  hasCustomers: { type: Boolean, default: false },
  hasProjects: { type: Boolean, default: false },
  registry: {
    /** @type {import('vue').PropType<{ internalCategories: Array<{ id: number; name: string }>, customers: Array<{ id: number; name: string }>, projects: Array<{ id: number; name: string }> }>} */
    type: Object,
    required: true,
  },
});

const emit = defineEmits(["add-entry"]);

const timer = useHoursTimer();

const manualHours = ref(/** @type {number | null} */ (null));
const description = ref("");
const registrationType = ref(
  /** @type {"internal" | "customer" | "project"} */ ("internal"),
);

const internalId = ref(/** @type {number | null} */ (null));
const customerId = ref(/** @type {number | null} */ (null));
const projectId = ref(/** @type {number | null} */ (null));
const taskId = ref(/** @type {number | null} */ (null));
const taskPickList = ref(
  /** @type {Array<{ id: number; title: string; hour_project_id: number }>} */ ([]),
);

const typePickOptions = computed(() => {
  /** @type {Array<{ label: string; value: "internal" | "customer" | "project"; disabled?: boolean }>} */
  const out = [];
  if (props.hasInternalCategories) {
    out.push({ label: strings.quickInternal, value: "internal" });
  }
  if (props.hasCustomers) {
    out.push({ label: strings.quickCustomer, value: "customer" });
  }
  if (props.hasProjects) {
    out.push({ label: strings.quickProject, value: "project" });
  }

  if (out.length === 0) {
    return [{ label: strings.quickInternal, value: "internal", disabled: true }];
  }

  return out;
});

const navDisabled = computed(
  () =>
    props.weekLocked ||
    (!props.hasInternalCategories && !props.hasCustomers && !props.hasProjects),
);

watch(
  () => [
    props.hasInternalCategories,
    props.hasCustomers,
    props.hasProjects,
  ],
  () => {
    if (props.hasInternalCategories) {
      registrationType.value = "internal";
      internalId.value = props.registry.internalCategories?.[0]?.id ?? null;

      return;
    }
    if (props.hasCustomers) {
      registrationType.value = "customer";
      customerId.value = props.registry.customers?.[0]?.id ?? null;

      return;
    }
    if (props.hasProjects) {
      registrationType.value = "project";
      projectId.value = props.registry.projects?.[0]?.id ?? null;
    }
    taskId.value = null;
  },
  { immediate: true },
);

watch(
  projectId,
  async (pid) => {
    taskId.value = null;
    if (!pid || registrationType.value !== "project") {
      taskPickList.value = [];

      return;
    }
    try {
      taskPickList.value = await fetchTasks(pid);
    } catch {
      taskPickList.value = [];
    }
  },
);

watch(registrationType, async (rt) => {
  taskPickList.value = [];
  taskId.value = null;
  if (rt === "internal") {
    internalId.value = props.registry.internalCategories?.[0]?.id ?? null;

    return;
  }
  if (rt === "customer") {
    customerId.value = props.registry.customers?.[0]?.id ?? null;

    return;
  }
  projectId.value = props.registry.projects?.[0]?.id ?? null;
  if (projectId.value) {
    taskPickList.value = await fetchTasks(projectId.value);
  }
});

function stopTimerIntoManual() {
  const hrs = timer.stopAndDrainHours();
  manualHours.value = (Number(manualHours.value) || 0) + hrs;
}

function submitEntry() {
  const fromTimer = timer.stopAndDrainHours();
  let dec = (Number(manualHours.value) || 0) + fromTimer;
  dec = Math.round(dec * 100) / 100;

  if (dec <= 0) {
    return;
  }

  const trimmed = description.value.trim();

  if (registrationType.value === "internal") {
    if (!internalId.value) {
      return;
    }
    emit("add-entry", {
      registration_type: "internal",
      internal_category_id: internalId.value,
      hours: dec,
      description: trimmed,
    });
    manualHours.value = null;
    description.value = "";

    return;
  }

  if (registrationType.value === "customer") {
    if (!customerId.value) {
      return;
    }
    emit("add-entry", {
      registration_type: "customer",
      customer_id: customerId.value,
      hours: dec,
      description: trimmed,
    });
    manualHours.value = null;
    description.value = "";

    return;
  }

  if (!projectId.value) {
    return;
  }

  if (taskId.value) {
    emit("add-entry", {
      registration_type: "task",
      hour_task_id: taskId.value,
      hours: dec,
      description: trimmed,
      _preset_project_ui: projectId.value,
    });
  } else {
    emit("add-entry", {
      registration_type: "project",
      hour_project_id: projectId.value,
      hours: dec,
      description: trimmed,
    });
  }

  manualHours.value = null;
  description.value = "";
}
</script>

<template>
  <div
    class="surface-card border-round-xl border border-surface-200 dark:border-surface-700 p-3 flex flex-wrap gap-3 items-end"
  >
    <div class="flex flex-wrap gap-3 items-end flex-grow">
      <div class="w-[9rem]">
        <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
          strings.quickAddHours
        }}</label>
        <InputNumber
          v-model="manualHours"
          suffix=" h"
          locale="en-US"
          mode="decimal"
          :min="0"
          :max-fraction-digits="2"
          :disabled="weekLocked"
          fluid
          class="max-w-[9rem]"
          input-class="text-sm"
          placeholder="0"
        />
      </div>

      <div class="w-[11rem] min-w-[10rem]">
        <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
          strings.quickRegistrationType
        }}</label>
        <Dropdown
          v-model="registrationType"
          class="w-full text-sm"
          option-label="label"
          option-value="value"
          :options="typePickOptions"
          :disabled="navDisabled"
        />
      </div>

      <div v-if="registrationType === 'internal'" class="w-[14rem] min-w-[12rem]">
        <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
          strings.quickInternal
        }}</label>
        <Dropdown
          v-model="internalId"
          class="w-full text-sm"
          option-label="name"
          option-value="id"
          :options="registry.internalCategories"
          :disabled="weekLocked || !hasInternalCategories"
        />
      </div>

      <div v-else-if="registrationType === 'customer'" class="w-[14rem] min-w-[12rem]">
        <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
          strings.quickCustomer
        }}</label>
        <Dropdown
          v-model="customerId"
          class="w-full text-sm"
          option-label="name"
          option-value="id"
          :options="registry.customers"
          :disabled="weekLocked || !hasCustomers"
        />
      </div>

      <div v-else class="flex flex-wrap gap-2 items-end">
        <div class="w-[14rem] min-w-[12rem]">
          <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
            strings.quickProject
          }}</label>
          <Dropdown
            v-model="projectId"
            class="w-full text-sm"
            option-label="name"
            option-value="id"
            :options="registry.projects"
            :disabled="weekLocked || !hasProjects"
          />
        </div>
        <div class="w-[14rem] min-w-[12rem]">
          <label class="text-xs font-medium block mb-1 text-surface-600 dark:text-surface-300">{{
            strings.quickTask
          }}</label>
          <Dropdown
            v-model="taskId"
            class="w-full text-sm"
            option-label="title"
            option-value="id"
            :show-clear="true"
            :options="taskPickList"
            :disabled="weekLocked || !hasProjects || !projectId"
            placeholder="—"
          />
        </div>
      </div>

      <div class="min-w-[12rem] flex-grow max-w-[28rem]">
        <BaseInputText v-model="description" :label="strings.quickDescription" class="text-sm" :disabled="weekLocked" />
      </div>
    </div>

    <div class="flex flex-wrap gap-2">
      <BaseButton
        v-if="!timer.running"
        variant="secondary"
        outlined
        size="small"
        :label="strings.startTimer"
        :disabled="weekLocked"
        @click="timer.start"
      />
      <BaseButton
        v-else
        variant="warning"
        size="small"
        :label="strings.stopTimer"
        :disabled="weekLocked"
        @click="stopTimerIntoManual"
      />
      <BaseButton variant="primary" size="small" :label="strings.addEntry" :disabled="weekLocked" @click="submitEntry" />
    </div>
  </div>
</template>
