<template>
  <div>
    <DefaultHeaderPage>
      <template #after>
        <q-btn
          outline
          icon="mdi-calendar"
          color="primary"
          @click="showFilter"
        />
      </template>
    </DefaultHeaderPage>
    <q-expansion-item
      v-model="filter"
      dense
      hide-expand-icon
      class="remove-header-expansion-item"
    >
      <DatePeriodSelector
        v-model:selected-period="defaultPeriod"
        v-model:selected-event-id="defaultEventId"
        class="q-pa-sm"
      />
    </q-expansion-item>

    <div v-if="!isLoading" class="column gap q-pa-sm">
      <div class="flex full-width gap">
        <div class="flex flex-grow gap">
          <CardIconMiniChart
            class="flex-grow"
            :title="t('dashboard.cards.total_earnings')"
            :icon="'mdi-currency-usd'"
            :number-porcent="paymentsChart.percentage_change"
            :number-card="
              t('dashboard.currency_format', {
                value: paymentsChart.current_total,
              })
            "
          >
            <template #chart>
              <MiniLineChart
                :data="paymentsChart.trend_data"
                fill-color="rgba(0, 0, 0, 0)"
              />
            </template>
          </CardIconMiniChart>
          <CardIconMiniChart
            class="flex-grow"
            :title="t('orders.plural')"
            :icon="'mdi-package-variant'"
            :number-porcent="ordersChart.percentage_change"
            :number-card="ordersChart.current_total"
          >
            <template #chart>
              <MiniBarChart
                :data="ordersChart.trend_data"
                fill-color="rgba(0, 0, 0, 0)"
              />
            </template>
          </CardIconMiniChart>
        </div>
        <div class="flex flex-grow gap">
          <CardIconMiniChart
            class="flex-grow"
            :title="t('dashboard.cards.tickets_sold')"
            :icon="'mdi-ticket-outline'"
            :number-porcent="ticketsSoldChart.percentage_change"
            :number-card="ticketsSoldChart.current_total"
          >
            <template #chart>
              <MiniLineChart
                :data="ticketsSoldChart.trend_data"
                fill-color="rgba(0, 0, 0, 0)"
              />
            </template>
          </CardIconMiniChart>
          <CardIconMiniChart
            class="flex-grow"
            :title="t('dashboard.cards.registrations')"
            :icon="'mdi-account-group-outline'"
            :number-porcent="participantsChart.percentage_change"
            :number-card="participantsChart.current_total"
          >
            <template #chart>
              <MiniBarChart
                :data="participantsChart.trend_data"
                fill-color="rgba(0, 0, 0, 0)"
              />
            </template>
          </CardIconMiniChart>
        </div>
      </div>

      <div class="flex full-width gap">
        <div class="flex flex-grow">
          <CardIconChart
            :title="t('dashboard.charts.tickets_by_type.title')"
            :icon="'mdi-ticket-account'"
            class="flex-grow"
          >
            <template #chart>
              <BarChart
                :data="eventTicketsByTypeChart"
                :data-set-label="t('events.tickets.plural')"
                :label-x="t('events.tickets.types_singular')"
                :label-y="t('common.terms.quantity')"
                :show-legend="true"
              />
            </template>
          </CardIconChart>
        </div>
        <div class="flex flex-grow">
          <CardIconChart
            :title="t('dashboard.charts.participants_by_document.title')"
            :icon="'mdi-badge-account'"
            class="flex-grow"
          >
            <template #chart>
              <DoughnutChart
                :data="eventParticipantsByCNPJAndCPF"
                :data-set-label="t('events.attendance.participant_plural')"
              />
            </template>
          </CardIconChart>
        </div>
      </div>

      <div class="flex full-width gap">
        <div class="flex flex-grow">
          <CardIconChart
            :title="t('dashboard.charts.sales_over_time.title')"
            :icon="'mdi-chart-line'"
            class="flex-grow"
          >
            <template #chart>
              <LineChart
                :data="salesOverTimeLineChart"
                :data-set-label="t('ui.navigation.sales')"
                :label-x="t('common.terms.month')"
                :label-y="
                  t('dashboard.charts.sales_over_time.y_label', {
                    currency: 'R$',
                  })
                "
              />
            </template>
          </CardIconChart>
        </div>
        <div class="flex flex-grow">
          <CardIconChart
            :title="t('dashboard.charts.registration_source.title')"
            :icon="'mdi-chart-pie'"
            class="flex-grow"
          >
            <template #chart>
              <PieChart
                :data="eventSourcePieChart"
                :data-set-label="
                  t('dashboard.charts.registration_source.source')
                "
              />
            </template>
          </CardIconChart>
        </div>
      </div>
    </div>

    <div v-else class="flex flex-center full-width q-pa-xl">
      <q-spinner color="primary" size="50px" />
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch, defineAsyncComponent } from "vue";
import { useI18n } from "vue-i18n";
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import DatePeriodSelector from "./components/DatePeriodSelector.vue";

const MiniLineChart = defineAsyncComponent(
  () => import("src/components/charts/mini/MiniLineChart.vue"),
);
const MiniBarChart = defineAsyncComponent(
  () => import("src/components/charts/mini/MiniBarChart.vue"),
);
const CardIconMiniChart = defineAsyncComponent(
  () => import("src/components/charts/CardIconMiniChart.vue"),
);
const CardIconChart = defineAsyncComponent(
  () => import("src/components/charts/CardIconChart.vue"),
);
const BarChart = defineAsyncComponent(
  () => import("src/components/charts/normal/BarChart.vue"),
);
const DoughnutChart = defineAsyncComponent(
  () => import("src/components/charts/normal/DoughnutChart.vue"),
);
const LineChart = defineAsyncComponent(
  () => import("src/components/charts/normal/LineChart.vue"),
);
const PieChart = defineAsyncComponent(
  () => import("src/components/charts/normal/PieChart.vue"),
);

const { t } = useI18n();

const isLoading = ref(true);
const filter = ref(false);
const defaultPeriod = ref("month");
const defaultEventId = ref(1);

const ordersChart = ref({});
const participantsChart = ref({});
const paymentsChart = ref({});
const ticketsSoldChart = ref({});
const eventTicketsByTypeChart = ref({});
const eventParticipantsByCNPJAndCPF = ref({});
const salesOverTimeLineChart = ref({});
const eventSourcePieChart = ref({});

const showFilter = () => {
  filter.value = !filter.value;
};

const generateMockData = () => {
  const createMiniChartData = (currentTotal, percentage) => ({
    current_total: currentTotal,
    percentage_change: percentage,
    trend_data: Array.from({ length: 10 }, () =>
      Math.floor(Math.random() * 100),
    ),
  });

  const barChartDataRaw = [
    {
      label: t("dashboard.charts.tickets_by_type.labels.vip"),
      value: Math.floor(Math.random() * 300),
    },
    {
      label: t("dashboard.charts.tickets_by_type.labels.track"),
      value: Math.floor(Math.random() * 800),
    },
    {
      label: t("dashboard.charts.tickets_by_type.labels.box"),
      value: Math.floor(Math.random() * 400),
    },
    {
      label: t("dashboard.charts.tickets_by_type.labels.courtesy"),
      value: Math.floor(Math.random() * 50),
    },
  ];

  const doughnutDataRaw = [
    {
      label: t("common.terms.cpf"),
      value: Math.floor(Math.random() * 900 + 100),
    },
    {
      label: t("common.terms.cnpj"),
      value: Math.floor(Math.random() * 100 + 10),
    },
  ];
  const doughnutTotal = doughnutDataRaw.reduce(
    (sum, item) => sum + item.value,
    0,
  );

  const lineChartDataRaw = [
    {
      label: t("common.months.january"),
      value: Math.floor(1200 + Math.random() * 500),
    },
    {
      label: t("common.months.february"),
      value: Math.floor(1900 + Math.random() * 500),
    },
    {
      label: t("common.months.march"),
      value: Math.floor(3000 + Math.random() * 500),
    },
    {
      label: t("common.months.april"),
      value: Math.floor(5000 + Math.random() * 500),
    },
    {
      label: t("common.months.may"),
      value: Math.floor(2300 + Math.random() * 500),
    },
    {
      label: t("common.months.june"),
      value: Math.floor(3200 + Math.random() * 500),
    },
  ];

  const pieDataRaw = [
    {
      label: t("dashboard.charts.registration_source.sources.instagram"),
      value: Math.floor(450 + Math.random() * 50),
    },
    {
      label: t("dashboard.charts.registration_source.sources.facebook"),
      value: Math.floor(250 + Math.random() * 50),
    },
    {
      label: t("dashboard.charts.registration_source.sources.google"),
      value: Math.floor(180 + Math.random() * 50),
    },
    {
      label: t("dashboard.charts.registration_source.sources.referral"),
      value: Math.floor(120 + Math.random() * 50),
    },
  ];
  const pieTotal = pieDataRaw.reduce((sum, item) => sum + item.value, 0);

  return {
    payments: createMiniChartData(
      (Math.random() * 20000 + 5000).toFixed(2),
      (Math.random() * 20 - 5).toFixed(2),
    ),
    orders: createMiniChartData(
      Math.floor(Math.random() * 500 + 50),
      (Math.random() * 15 - 5).toFixed(2),
    ),
    tickets_sold: createMiniChartData(
      Math.floor(Math.random() * 1500 + 200),
      (Math.random() * 25 - 5).toFixed(2),
    ),
    participants: createMiniChartData(
      Math.floor(Math.random() * 1000 + 100),
      (Math.random() * 10 - 5).toFixed(2),
    ),
    barData: {
      chart_data: barChartDataRaw,
    },
    doughnutData: {
      chart_data: doughnutDataRaw,
      current_total: doughnutTotal,
    },
    lineData: {
      chart_data: lineChartDataRaw,
    },
    pieData: {
      chart_data: pieDataRaw,
      current_total: pieTotal,
    },
  };
};

const updateDashboardData = async () => {
  isLoading.value = true;
  setTimeout(() => {
    const mockData = generateMockData();

    ordersChart.value = mockData.orders;
    participantsChart.value = mockData.participants;
    paymentsChart.value = mockData.payments;
    ticketsSoldChart.value = mockData.tickets_sold;

    eventTicketsByTypeChart.value = mockData.barData;
    eventParticipantsByCNPJAndCPF.value = mockData.doughnutData;
    salesOverTimeLineChart.value = mockData.lineData;
    eventSourcePieChart.value = mockData.pieData;

    isLoading.value = false;
  }, 500);
};

watch([defaultPeriod, defaultEventId], async () => {
  await updateDashboardData();
});

onMounted(async () => {
  await updateDashboardData();
});
</script>

<style scoped>
.gap {
  gap: 16px;
}
</style>
