<template>
  <div>
    <DefaultHeaderPage />

    <div class="q-pa-sm">
      <div class="stat-cards-row q-mb-md">
        <DashboardStatCard
          :badge="`${totalAlunos} ativos`"
          :value="String(totalAlunos)"
          icon="mdi-account-multiple-outline"
          title="Total alunos (contratos ativos)"
        />

        <!-- TODO: usar dados reais de receita (zerado por enquanto). -->

        <DashboardStatCard
          icon="mdi-currency-usd"
          subtitle="0 pagamentos pendentes"
          title="Receita Total"
          value="R$ 0,00"
        />

        <!-- TODO: usar dados reais de ticket médio (zerado por enquanto). -->

        <DashboardStatCard
          icon="mdi-calendar-blank"
          subtitle="Estável"
          title="Ticket Médio"
          value="R$ 0,00"
        />

        <DashboardStatCard
          :value="String(aniversariantes.length)"
          icon="mdi-emoticon-happy-outline"
          subtitle="Fortaleça seus relacionamentos"
          title="Aniversariantes"
        />
      </div>

      <div class="row q-col-gutter-md q-mb-md items-stretch">
        <div class="col-12 col-md-5">
          <DashboardChartCard
            style="height: 100%"
            title="Faturamento Serviço / Materiais"
          >
            <GroupedBarChart
              :datasets="faturamentoChart.datasets"
              :labels="faturamentoChart.labels"
              :tick-formatter="formatCurrencyTick"
              :tooltip-formatter="formatCurrencyTooltip"
              class="full-width full-height"
              label-y="R$"
            />
          </DashboardChartCard>
        </div>

        <div class="col-12 col-md-4">
          <q-card
            bordered
            class="full-height"
            flat
          >
            <q-card-section
              class="row justify-between items-center q-pb-xs"
            >
              <span class="text-subtitle2 text-weight-medium">
                Contratos Ativos
              </span>

              <q-icon
                color="grey-5"
                name="mdi-trending-up"
              />
            </q-card-section>

            <q-separator />

            <q-card-section
              class="flex flex-center q-pt-sm"
              style="height: calc(100% - 57px); position: relative"
            >
              <div style="height: 100%; max-width: 280px; width: 100%">
                <Doughnut
                  :data="gaugeData"
                  :options="gaugeOptions"
                  :plugins="[gaugeNeedlePlugin]"
                />
              </div>

              <div class="gauge-label">
                <div class="text-h5 text-bold">
                  {{ activeContracts }}
                </div>

                <div class="text-caption text-grey-6">
                  Ativos
                </div>
              </div>
            </q-card-section>
          </q-card>
        </div>

        <div class="col-12 col-md-3">
          <q-card
            bordered
            class="full-height"
            flat
          >
            <q-card-section
              class="row justify-between items-center q-pb-xs"
            >
              <span class="text-subtitle2 text-weight-medium">
                Atalhos rápidos
              </span>

              <q-icon
                color="grey-5"
                name="mdi-apps"
              />
            </q-card-section>

            <q-separator />

            <q-card-section class="q-pt-md column q-gutter-sm">
              <q-btn
                v-if="canAdd"
                class="full-width"
                color="primary"
                label="Criar contrato"
                no-caps
                unelevated
                @click="onCriarContrato"
              />

              <q-btn
                v-if="canEditClasses"
                class="full-width"
                color="primary"
                label="Registrar presença"
                no-caps
                unelevated
                @click="onRegistrarPresenca"
              />

              <div
                v-if="canAddOrders"
                class="full-width cursor-not-allowed"
              >
                <q-btn
                  class="full-width"
                  color="primary"
                  disable
                  label="Novo pedido"
                  no-caps
                  unelevated
                />

                <q-tooltip>
                  Esta funcionalidade ainda não foi desenvolvida.
                </q-tooltip>
              </div>
            </q-card-section>
          </q-card>
        </div>
      </div>

      <div class="row q-col-gutter-md items-stretch">
        <div class="col-12 col-md-5">
          <q-card class="card-ring full-height feriados-card" flat>
            <div class="flex justify-between items-center no-wrap q-mb-sm">
              <span class="text-subtitle2 text-weight-regular">
                Feriados do mês
              </span>

              <q-btn
                color="grey-5"
                dense
                flat
                icon="mdi-calendar-star"
                round
                @click="openFeriadosDialog"
              />
            </div>

            <q-btn
              v-if="canAdd"
              class="full-width q-mb-md"
              color="primary"
              label="Nova data"
              no-caps
              unelevated
              @click="openFeriadosDialog"
            />

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

            <div
              v-else-if="feriadosMes.length === 0"
              class="text-caption text-grey-5 text-center q-mt-sm"
            >
              Nenhum feriado neste mês.
            </div>

            <div
              v-else
              class="row q-gutter-sm"
            >
              <div
                v-for="feriado in feriadosMes"
                :key="feriado.id"
                class="column items-center cursor-pointer"
                style="min-width: 52px"
                @click="openEditFromDashboard(feriado)"
              >
                <q-badge
                  class="text-subtitle1 text-bold q-pa-sm"
                  color="deep-orange"
                  style="min-width: 40px; justify-content: center"
                >
                  {{ feriado.dia }}
                </q-badge>

                <div class="text-caption q-mt-xs text-center">
                  {{ feriado.nome }}
                </div>
              </div>
            </div>
          </q-card>
        </div>

        <div class="col-12 col-md-4">
          <DashboardChartCard
            style="height: 100%"
            title="Matrículas por Período"
          >
            <GroupedBarChart
              :bar-percentage="0.85"
              :bar-radius="50"
              :category-percentage="0.6"
              :datasets="matriculasChart.datasets"
              :labels="matriculasChart.labels"
              :max-bar-thickness="44"
              :show-datalabels="true"
              class="full-width full-height"
            />
          </DashboardChartCard>
        </div>

        <div class="col-12 col-md-3">
          <AniversariantesCard
            :people="aniversariantes"
            style="height: 100%"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ArcElement, Chart as ChartJS, Legend, Tooltip } from "chart.js";
import { computed, onMounted, ref, watch } from "vue";
import { Doughnut } from "vue-chartjs";
import { getDashboardSummary } from "src/api/franchisee_dashboard";
import { getHolidays } from "src/api/holiday";
import { permissionStore } from "src/stores/permission";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import { userStore } from "src/stores/user";

import AniversariantesCard from "src/components/charts/AniversariantesCard.vue";
import DashboardChartCard from "src/components/charts/DashboardChartCard.vue";
import DashboardStatCard from "src/components/charts/DashboardStatCard.vue";
import GroupedBarChart from "src/components/charts/normal/GroupedBarChart.vue";
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import AddEditContractDialog from "src/pages/students/components/AddEditContractDialog.vue";
import FeriadosDialog from "./components/FeriadosDialog.vue";
import FeriadosEditDialog from "./components/FeriadosEditDialog.vue";

ChartJS.register(ArcElement, Tooltip, Legend);

const $q = useQuasar();
const router = useRouter();

const permissions = permissionStore();
const store = userStore();

const activeContracts = ref(0);
const allHolidays = ref([]);
const aniversariantes = ref([]);
const feriadosLoading = ref(false);
const students = ref([]);
const totalAlunos = ref(0);

const gaugeData = ref({
  datasets: [
    {
      backgroundColor: [
        "#00a550",
        "#4dbb7e",
        "#9ad2ad",
        "#cce156",
        "#fff100",
        "#ffbe00",
        "#ff8c00",
        "#FC3D23",
        "#D01616",
        "#8A0000",
      ],
      borderColor: "transparent",
      data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      needleValue: 0,
    },
  ],
});

const gaugeOptions = ref({
  circumference: 180,
  cutout: "50%",
  maintainAspectRatio: false,
  plugins: {
    datalabels: {
      color: "black",
      font: {
        size: 14,
        weight: "bold",
      },
      formatter: (_value, context) => context.dataIndex,
    },
    legend: {
      display: false,
    },
    tooltip: {
      enabled: false,
    },
  },
  responsive: true,
  rotation: 270,
});

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

const canAddOrders = computed(() =>
  permissions.getAccess("franchisee_orders", "add"),
);

const canEditClasses = computed(() =>
  permissions.getAccess("franchisee_classes", "edit"),
);

const feriadosMes = computed(() => {
  const now = new Date();
  const month = now.getMonth() + 1;
  const year = now.getFullYear();

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

      return (
        date.getMonth() + 1 === month &&
        date.getFullYear() === year
      );
    })
    .sort(
      (firstHoliday, secondHoliday) =>
        new Date(firstHoliday.holiday_date) -
        new Date(secondHoliday.holiday_date),
    )
    .map((holiday) => ({
      base_holiday_id: holiday.base_holiday_id ?? null,
      description: holiday.description,
      dia: new Date(`${holiday.holiday_date}T00:00:00`).getDate(),
      holiday_date: holiday.holiday_date,
      id: holiday.id,
      nome: holiday.description,
      type: holiday.type,
    }));
});

const matriculasChart = computed(() => {
  const now = new Date();
  const start = new Date(now.getFullYear(), now.getMonth() - 5, 1);

  const counts = {};

  for (const student of students.value) {
    if (!student.created_at) continue;

    const date = new Date(student.created_at.replace(" ", "T"));

    if (date < start) continue;

    const key = `${date.getFullYear()}-${date.getMonth()}`;

    counts[key] = (counts[key] ?? 0) + 1;
  }

  const data = [];
  const labels = [];

  for (let index = 0; index < 6; index++) {
    const month = new Date(
      start.getFullYear(),
      start.getMonth() + index,
      1,
    );

    const key = `${month.getFullYear()}-${month.getMonth()}`;

    labels.push(MONTHS_PT[month.getMonth()]);
    data.push(counts[key] ?? 0);
  }

  return {
    datasets: [
      {
        color: MATRICULA_COLORS,
        data,
        label: "Matrículas",
      },
    ],
    labels,
  };
});

// Faturamento Serviço / Materiais — zerado (sem fluxo de dados ainda),
// igual ao Franqueador.
// TODO: alimentar com dados reais de faturamento de serviço/materiais.
const faturamentoChart = {
  datasets: [
    {
      color: "#a274f1",
      data: [],
      label: "Serviço",
    },
    {
      color: "#ff9999",
      data: [],
      label: "Materiais",
    },
  ],
  labels: [],
};

const gaugeNeedlePlugin = {
  id: "gaugeNeedle",

  afterDatasetsDraw(chart) {
    const { ctx, data } = chart;

    const meta = chart.getDatasetMeta(0).data[0];
    const needleValue = data.datasets[0].needleValue;
    const outerRadius = meta.outerRadius - 20;
    const xCenter = meta.x;
    const yCenter = meta.y;

    const circumference =
      (meta.circumference / Math.PI / data.datasets[0].data[0]) *
      needleValue;

    const angle = Math.PI;

    ctx.save();
    ctx.translate(xCenter, yCenter);
    ctx.rotate(angle * (circumference + 1.5));

    ctx.beginPath();
    ctx.fillStyle = "grey";
    ctx.strokeStyle = "grey";
    ctx.moveTo(-3, 0);
    ctx.lineTo(0, -outerRadius);
    ctx.lineTo(3, 0);
    ctx.stroke();
    ctx.fill();

    ctx.beginPath();
    ctx.arc(0, 0, 6, 0, 2 * Math.PI);
    ctx.fillStyle = "grey";
    ctx.fill();

    ctx.restore();
  },
};

const MATRICULA_COLORS = [
  "#3B82F6",
  "#EF4444",
  "#A855F7",
  "#374151",
  "#EAB308",
  "#06B6D4",
];

const MONTHS_PT = [
  "JAN",
  "FEV",
  "MAR",
  "ABR",
  "MAI",
  "JUN",
  "JUL",
  "AGO",
  "SET",
  "OUT",
  "NOV",
  "DEZ",
];

const fetchHolidays = async () => {
  feriadosLoading.value = true;

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

const fetchSummary = async () => {
  try {
    const summary = await getDashboardSummary();

    activeContracts.value = summary.contracts.active;
    aniversariantes.value = summary.birthdays;
    students.value = summary.enrollments;
    totalAlunos.value = summary.students_count;

    gaugeData.value.datasets[0].needleValue = Math.min(
      activeContracts.value,
      10,
    );
  } catch {
    // silencioso
  }
};

const formatCurrencyTick = (value) => {
  if (value >= 1000) {
    return `R$ ${(value / 1000).toFixed(0)}k`;
  }

  return `R$ ${value}`;
};

const formatCurrencyTooltip = (context) => {
  const value = context.parsed.y;

  return ` ${context.dataset.label}: R$ ${value.toLocaleString("pt-BR", {
    minimumFractionDigits: 2,
  })}`;
};

const onCriarContrato = () => {
  $q.dialog({
    component: AddEditContractDialog,
    componentProps: {
      selectStudent: true,
    },
  }).onOk(fetchSummary);
};

const onRegistrarPresenca = () => {
  router.push({ name: "ClassPage" });
};

const openEditFromDashboard = (feriado) => {
  $q.dialog({
    component: FeriadosEditDialog,
    componentProps: {
      holiday: feriado,
    },
  }).onOk(({ action, holiday: updated, id }) => {
    if (action === "update") {
      const index = allHolidays.value.findIndex(
        (holiday) => holiday.id === updated.id,
      );

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

      return;
    }

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

const openFeriadosDialog = () => {
  $q.dialog({
    component: FeriadosDialog,
  }).onOk(fetchHolidays);
};

watch(
  () => store.selectedUnit?.id,
  (newId, oldId) => {
    if (!newId || newId === oldId) return;

    fetchSummary();
    fetchHolidays();
  },
);

onMounted(() => {
  fetchHolidays();
  fetchSummary();
});
</script>

<style scoped>
.stat-cards-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 16px;
}

.stat-cards-row > * {
  flex: 1 1 0;
  min-width: 0;
}

.gauge-label {
  position: absolute;
  bottom: 28%;
  left: 50%;
  pointer-events: none;
  text-align: center;
  transform: translateX(-50%);
}

.feriados-card {
  display: flex;
  flex-direction: column;
  padding: 20px 24px;
  border-radius: 12px;
}

@media (max-width: 599px) {
  .stat-cards-row {
    flex-wrap: wrap;
  }

  .stat-cards-row > * {
    flex: 1 1 calc(50% - 8px);
  }
}
</style>