<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <q-card class="q-dialog-plugin dialog-form-card feriados-dialog">
      <template v-if="view === 'calendar'">
        <DefaultDialogHeader
          title="Feriados"
          @close="onClose"
        />

        <q-scroll-area class="dialog-form-scroll">
          <q-card-section class="row q-col-gutter-md q-pt-none">
            <div class="col-12 col-sm-7">
              <div class="row items-center justify-between q-mb-md">
                <q-btn
                  color="grey-7"
                  dense
                  flat
                  icon="mdi-chevron-left"
                  round
                  @click="prevMonth"
                />

                <div class="row items-center q-gutter-xs">
                  <DefaultSelect
                    v-model="currentMonth"
                    dense
                    emit-value
                    map-options
                    outlined
                    style="min-width: 100px"
                    :options="monthOptions"
                  />

                  <DefaultSelect
                    v-model="currentYear"
                    dense
                    emit-value
                    map-options
                    outlined
                    style="min-width: 80px"
                    :options="yearOptions"
                  />
                </div>

                <q-btn
                  color="grey-7"
                  dense
                  flat
                  icon="mdi-chevron-right"
                  round
                  @click="nextMonth"
                />
              </div>

              <div class="calendar-grid q-mb-xs">
                <div
                  v-for="day in weekDays"
                  :key="day"
                  class="cal-header text-caption text-grey-6 text-center text-weight-medium"
                >
                  {{ day }}
                </div>
              </div>

              <div class="calendar-grid">
                <div
                  v-for="(cell, index) in calendarCells"
                  :key="index"
                  :class="{
                    'cal-cell--empty': !cell.day,
                    'cal-cell--holiday': cell.isHoliday,
                  }"
                  class="cal-cell"
                  @click="
                    canAdd &&
                    cell.day &&
                    !cell.isHoliday &&
                    openNewRecord(cell.day)
                  "
                >
                  <span
                    v-if="cell.day"
                    class="cal-cell__number"
                  >
                    {{ cell.day }}
                  </span>
                </div>
              </div>
            </div>

            <div class="col-12 col-sm-5">
              <div class="text-subtitle2 q-mb-sm">
                Resumo
              </div>

              <q-separator class="q-mb-sm" />

              <div
                v-if="loadingHolidays"
                class="flex flex-center q-py-lg"
              >
                <q-spinner
                  color="primary"
                  size="24px"
                />
              </div>

              <div
                v-else-if="monthHolidays.length === 0"
                class="text-caption text-grey-5 text-center q-mt-lg q-px-sm"
              >
                Clique em um dia no calendário para adicionar um registro.
              </div>

              <q-list
                v-else
                separator
              >
                <q-item
                  v-for="holiday in monthHolidays"
                  :key="holiday.id"
                  class="q-pa-sm cursor-pointer"
                  clickable
                  @click="openEdit(holiday)"
                >
                  <q-item-section avatar>
                    <q-avatar
                      class="text-weight-bold"
                      color="deep-orange"
                      size="36px"
                      text-color="white"
                    >
                      {{ holiday.day }}
                    </q-avatar>
                  </q-item-section>

                  <q-item-section>
                    <q-item-label class="text-body2">
                      {{ holiday.description }}
                    </q-item-label>

                    <q-item-label caption>
                      {{ typeLabel(holiday.type) }}
                    </q-item-label>
                  </q-item-section>

                  <q-item-section side>
                    <q-icon
                      :color="
                        holiday.base_holiday_id ? 'grey-4' : 'grey-5'
                      "
                      :name="
                        holiday.base_holiday_id
                          ? 'mdi-lock-outline'
                          : 'mdi-pencil-outline'
                      "
                      size="xs"
                    />
                  </q-item-section>
                </q-item>
              </q-list>

              <div
                v-if="monthHolidays.length > 0"
                class="text-caption text-grey-5 text-center q-mt-md q-px-sm"
              >
                Clique em um dia no calendário para adicionar um registro.
              </div>
            </div>
          </q-card-section>
        </q-scroll-area>

        <q-card-actions
          align="right"
          class="q-px-md q-pb-md"
        >
          <q-btn
            color="primary"
            label="Fechar"
            no-caps
            outline
            @click="onClose"
          />
        </q-card-actions>
      </template>

      <template v-else>
        <DefaultDialogHeader
          :title="`Novo Registro: ${formattedSelectedDate}`"
          @close="cancelNewRecord"
        />

        <DefaultForm @submit="saveNewRecord">
          <q-scroll-area class="dialog-form-scroll">
            <q-card-section class="column q-gutter-md q-pt-sm">
              <DefaultInput
                v-model="newDescription"
                autofocus
                icon="mdi-pencil-outline"
                label="Nome do Evento"
                outlined
                placeholder="Ex: Ponto facultativo, Natal..."
                :rules="[inputRules.required]"
              />

              <DefaultSelect
                v-model="newType"
                emit-value
                label="Selecione o Tipo."
                map-options
                outlined
                :options="typeOptions"
              />
            </q-card-section>
          </q-scroll-area>

          <q-card-actions
            align="right"
            class="q-px-md q-pb-md"
          >
            <q-btn
              color="primary"
              label="Cancelar"
              no-caps
              outline
              @click="cancelNewRecord"
            />

            <q-btn
              color="primary"
              label="Salvar"
              no-caps
              type="submit"
              :disable="!newDescription.trim()"
              :loading="saving"
            />
          </q-card-actions>
        </DefaultForm>
      </template>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { createHoliday, getHolidays } from "src/api/holiday";
import { computed, onMounted, ref } from "vue";
import { useDialogPluginComponent, useQuasar } from "quasar";
import { useInputRules } from "src/composables/useInputRules";
import { permissionStore } from "src/stores/permission";

import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultForm from "src/components/defaults/DefaultForm.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import FeriadosEditDialog from "src/pages/dashboard/components/FeriadosEditDialog.vue";

defineEmits([...useDialogPluginComponent.emits]);

const { dialogRef, onDialogHide, onDialogOK } =
  useDialogPluginComponent();

const $q = useQuasar();
const { inputRules } = useInputRules();

const permissions = permissionStore();

const currentMonth = ref(new Date().getMonth() + 1);
const currentYear = ref(new Date().getFullYear());
const existingHolidays = ref([]);
const loadingHolidays = ref(false);
const newDescription = ref("");
const newType = ref("feriado");
const saving = ref(false);
const selectedDay = ref(null);
const view = ref("calendar");

const canAdd = computed(() =>
  permissions.getAccess("franchisee_dashboard", "add"),
);

const calendarCells = computed(() => {
  const daysInMonth = new Date(
    currentYear.value,
    currentMonth.value,
    0,
  ).getDate();

  const firstDay = new Date(
    currentYear.value,
    currentMonth.value - 1,
    1,
  ).getDay();

  const holidayDays = new Set(
    monthHolidays.value.map((holiday) => holiday.day),
  );

  const cells = [];

  for (let index = 0; index < firstDay; index++) {
    cells.push({
      day: null,
      isHoliday: false,
    });
  }

  for (let day = 1; day <= daysInMonth; day++) {
    cells.push({
      day,
      isHoliday: holidayDays.has(day),
    });
  }

  return cells;
});

const formattedSelectedDate = computed(() => {
  if (!selectedDay.value) return "";

  const day = String(selectedDay.value).padStart(2, "0");
  const month = String(currentMonth.value).padStart(2, "0");

  return `${day}/${month}/${currentYear.value}`;
});

const monthHolidays = computed(() =>
  existingHolidays.value
    .filter((holiday) => {
      const date = new Date(`${holiday.holiday_date}T00:00:00`);

      return (
        date.getMonth() + 1 === currentMonth.value &&
        date.getFullYear() === currentYear.value
      );
    })
    .map((holiday) => {
      const date = new Date(`${holiday.holiday_date}T00:00:00`);

      return {
        ...holiday,
        day: date.getDate(),
      };
    })
    .sort(
      (firstHoliday, secondHoliday) =>
        firstHoliday.day - secondHoliday.day,
    ),
);

const yearOptions = computed(() => {
  const baseYear = new Date().getFullYear();

  return Array.from({ length: 7 }, (_, index) => {
    const year = baseYear - 2 + index;

    return {
      label: String(year),
      value: year,
    };
  });
});

const monthOptions = [
  { label: "Jan", value: 1 },
  { label: "Fev", value: 2 },
  { label: "Mar", value: 3 },
  { label: "Abr", value: 4 },
  { label: "Mai", value: 5 },
  { label: "Jun", value: 6 },
  { label: "Jul", value: 7 },
  { label: "Ago", value: 8 },
  { label: "Set", value: 9 },
  { label: "Out", value: 10 },
  { label: "Nov", value: 11 },
  { label: "Dez", value: 12 },
];

const typeOptions = [
  { label: "Feriado", value: "feriado" },
  { label: "Ponto Facultativo", value: "facultativo" },
];

const weekDays = [
  "Dom",
  "Seg",
  "Ter",
  "Qua",
  "Qui",
  "Sex",
  "Sáb",
];

const cancelNewRecord = () => {
  selectedDay.value = null;
  view.value = "calendar";
};

const loadHolidays = async () => {
  loadingHolidays.value = true;

  try {
    existingHolidays.value = await getHolidays();
  } catch {
    $q.notify({
      message: "Erro ao carregar feriados.",
      type: "negative",
    });
  } finally {
    loadingHolidays.value = false;
  }
};

const nextMonth = () => {
  if (currentMonth.value === 12) {
    currentMonth.value = 1;
    currentYear.value += 1;

    return;
  }

  currentMonth.value += 1;
};

const onClose = () => {
  onDialogOK(true);
};

const openEdit = (holiday) => {
  $q.dialog({
    component: FeriadosEditDialog,
    componentProps: {
      holiday,
    },
  }).onOk(({ action, holiday: updatedHoliday, id }) => {
    if (action === "update") {
      const index = existingHolidays.value.findIndex(
        (item) => item.id === updatedHoliday.id,
      );

      if (index !== -1) {
        existingHolidays.value[index] = {
          ...existingHolidays.value[index],
          ...updatedHoliday,
        };
      }

      return;
    }

    if (action === "delete") {
      existingHolidays.value = existingHolidays.value.filter(
        (item) => item.id !== id,
      );
    }
  });
};

const openNewRecord = (day) => {
  newDescription.value = "";
  newType.value = "feriado";
  selectedDay.value = day;
  view.value = "new-record";
};

const prevMonth = () => {
  if (currentMonth.value === 1) {
    currentMonth.value = 12;
    currentYear.value -= 1;

    return;
  }

  currentMonth.value -= 1;
};

const saveNewRecord = async () => {
  const description = newDescription.value.trim();

  if (!description || selectedDay.value === null) return;

  const day = String(selectedDay.value).padStart(2, "0");
  const month = String(currentMonth.value).padStart(2, "0");

  saving.value = true;

  try {
    await createHoliday({
      description,
      holiday_date: `${currentYear.value}-${month}-${day}`,
      type: newType.value,
    });

    await loadHolidays();

    selectedDay.value = null;
    view.value = "calendar";
  } catch {
    $q.notify({
      message: "Erro ao salvar feriado. Tente novamente.",
      type: "negative",
    });
  } finally {
    saving.value = false;
  }
};

const typeLabel = (type) =>
  type === "facultativo" ? "Ponto Facultativo" : "Feriado";

onMounted(loadHolidays);
</script>

<style scoped>
.feriados-dialog {
  width: 900px;
  max-width: 95vw;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.cal-header {
  padding: 6px 0 4px;
  font-weight: 600;
  text-align: center;
}

.cal-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.15s;
}

.cal-cell:hover:not(.cal-cell--empty):not(.cal-cell--holiday) {
  background: #f5f5f5;
}

.cal-cell--empty {
  cursor: default;
  pointer-events: none;
}

.cal-cell--holiday {
  cursor: default;
}

.cal-cell__number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
}

.cal-cell--holiday .cal-cell__number {
  color: #fff;
  background: #e64a19;
  font-weight: 700;
}
</style>