<template>
  <q-page class="service-package-page bg-page q-pb-xl">
    <div class="row items-center q-px-md q-pt-md q-pb-sm bg-white shadow-service-package">
      <q-btn
        class="header-back-btn"
        color="primary"
        dense
        flat
        icon="mdi-chevron-left"
        round
        @click="router.back()"
      />

      <div
        class="col text-center font16 fontbold gradient-diarista text-primary"
      >
        {{ $t("service_package.title") }}
      </div>

      <div style="width: 36px"></div>
    </div>

    <div
      v-if="servicePackage.items.length === 0"
      class="q-px-md q-pt-md"
    >
      <q-card
        :flat="false"
        class="empty-card bg-surface shadow-card card-border"
      >
        <q-card-section class="column items-center text-center q-pa-lg">
          <q-icon
            color="grey-5"
            name="mdi-shopping-outline"
            size="42px"
          />

          <span class="font14 fontbold text-text q-mt-sm">
            {{ $t("service_package.empty_title") }}
          </span>

          <span class="font12 text-grey-7 q-mt-xs">
            {{ $t("service_package.empty_message") }}
          </span>

          <q-btn
            class="q-mt-md"
            color="primary"
            no-caps
            padding="8px 18px"
            rounded
            unelevated
            :label="$t('service_package.view_favorites')"
            @click="router.push({ name: 'ProfilePage' })"
          />
        </q-card-section>
      </q-card>

      <q-card
        v-if="servicePackage.lastCreatedGroup"
        :flat="false"
        class="created-card bg-surface shadow-card card-border q-mt-md"
      >
        <q-card-section class="q-pa-md">
          <div class="row items-center no-wrap">
            <q-icon
              color="positive"
              name="mdi-check-circle-outline"
              size="24px"
            />

            <div class="column q-ml-sm">
              <span class="font14 fontbold text-text">
                {{ $t("service_package.last_request_title") }}
              </span>

              <span class="font12 text-grey-7">
                {{
                  $t("service_package.created_count", {
                    count: servicePackage.lastCreatedGroup.schedule_ids.length,
                  })
                }}
              </span>
            </div>
          </div>
        </q-card-section>
      </q-card>
    </div>

    <template v-else>
      <div class="q-px-md q-pt-md column q-gutter-y-sm">
        <div class="service-package-discount-banner row items-center no-wrap q-pa-sm">
          <q-icon
            color="positive"
            name="mdi-sale-outline"
            size="20px"
          />

          <span class="font12 fontbold text-positive q-ml-sm">
            {{ servicePackageDiscountMessage }}
          </span>
        </div>

        <q-card
          v-for="(item, index) in servicePackage.items"
          :key="item.local_id"
          :flat="false"
          class="service-package-item-card bg-surface shadow-card card-border"
        >
          <q-card-section class="row no-wrap q-pa-md">
            <q-avatar
              color="indigo-1"
              size="44px"
              text-color="indigo-4"
            >
              <img
                v-if="getProfileMediaUrl(item)"
                :src="getProfileMediaUrl(item)"
                style="object-fit: cover"
              />

              <span v-else>
                {{ getProviderInitial(item) }}
              </span>
            </q-avatar>

            <div class="column col q-ml-sm">
              <span class="font14 fontbold text-text">
                {{ item.provider_name }}
              </span>

              <span class="font12 text-grey-7">
                {{ formatDate(item.date) }}
              </span>

              <span class="font12 text-grey-7">
                {{
                  $t("service_package.time_range", {
                    start: item.start_time,
                    end: item.end_time,
                  })
                }}
              </span>

              <div class="row items-center q-gutter-x-sm q-mt-xs">
                <q-chip
                  class="font10"
                  color="purple-1"
                  dense
                  square
                  text-color="primary"
                >
                  {{
                    $t("service_package.hours_short", { hours: item.period_type })
                  }}
                </q-chip>

                <q-chip
                  class="font10"
                  color="grey-2"
                  dense
                  square
                  text-color="grey-8"
                >
                  {{
                    item.offers_meal
                      ? $t("service_package.with_meal")
                      : $t("service_package.without_meal")
                  }}
                </q-chip>
              </div>

              <div class="item-prices q-mt-sm">
                <div
                  v-if="!hasServicePackageDiscount"
                  class="row items-center no-wrap"
                >
                  <span class="font11 fontbold text-primary">{{
                    $t("service_package.pix_total")
                  }}</span>

                  <q-space />

                  <span class="font12 fontbold text-primary">
                    {{ formatCurrencyValue(getStandardPixItemTotal(item)) }}
                  </span>
                </div>

                <div
                  v-if="!hasServicePackageDiscount"
                  class="row items-center no-wrap q-mt-xs"
                >
                  <span class="font11 text-grey-7">
                    {{ $t("service_package.credit_card_total") }}
                  </span>

                  <q-space />

                  <span class="font12 fontbold text-text">
                    {{ formatCurrencyValue(getCreditCardItemTotal(item)) }}
                  </span>
                </div>

                <div
                  v-if="hasServicePackageDiscount"
                  class="row items-center no-wrap q-mt-xs"
                >
                  <span class="font11 fontbold text-positive">
                    {{ $t("service_package.discount_total") }}
                  </span>

                  <q-space />

                  <span class="font12 fontbold text-positive">
                    {{ formatCurrencyValue(getServicePackageDiscountItemTotal(item)) }}
                  </span>
                </div>
              </div>
            </div>

            <q-btn
              color="negative"
              dense
              flat
              icon="mdi-delete-outline"
              round
              @click="servicePackage.removeItem(index)"
            />
          </q-card-section>
        </q-card>
      </div>

      <div class="q-px-md q-pt-md">
        <q-card
          :flat="false"
          class="checkout-card bg-surface shadow-card card-border"
        >
          <q-card-section class="q-pa-md">
            <div class="row items-center no-wrap q-mb-sm">
              <span class="font14 fontbold text-primary">
                {{ $t("service_package.summary") }}
              </span>

              <q-space />
            </div>

            <div class="summary-row row items-center no-wrap q-py-xs">
              <span class="font12 text-grey-7">
                {{ $t("service_package.provider") }}
              </span>

              <q-space />

              <span class="font12 fontbold text-text text-right">
                {{ providerName }}
              </span>
            </div>

            <div class="summary-row row items-center no-wrap q-py-xs">
              <span class="font12 text-grey-7">
                {{ $t("service_package.address") }}
              </span>

              <q-space />

              <span class="font12 fontbold text-text text-right">
                {{ primaryAddressLabel }}
              </span>
            </div>

            <div class="summary-row row items-center no-wrap q-py-xs">
              <span class="font12 text-grey-7">
                {{ $t("service_package.quantity") }}
              </span>

              <q-space />

              <span class="font12 fontbold text-text">
                {{
                  $t("service_package.schedule_count", {
                    count: servicePackage.items.length,
                  })
                }}
              </span>
            </div>

            <div
              v-if="!hasServicePackageDiscount"
              class="summary-row row items-center no-wrap q-py-xs"
            >
              <span class="font12 fontbold text-primary">
                {{ $t("service_package.pix_total") }}
              </span>

              <q-space />

              <span class="font14 fontbold text-primary">
                {{ formatCurrencyValue(pixTotalAmount) }}
              </span>
            </div>

            <div
              v-if="hasServicePackageDiscount"
              class="summary-row row items-center no-wrap q-py-xs"
            >
              <span class="font12 fontbold text-positive">
                {{ $t("service_package.discount_total") }}
              </span>

              <q-space />

              <span class="font14 fontbold text-positive">
                {{ formatCurrencyValue(servicePackageDiscountTotalAmount) }}
              </span>
            </div>

            <div
              v-if="pixDiscountAmount > 0"
              class="summary-discount row items-center no-wrap q-py-xs q-px-sm q-mt-sm"
            >
              <q-icon
                color="positive"
                name="mdi-tag-outline"
                size="18px"
              />

              <span class="font12 fontbold text-positive q-ml-xs">
                {{
                  $t("service_package.discount_saved", {
                    value: formatPrice(pixDiscountAmount),
                  })
                }}
              </span>
            </div>
          </q-card-section>

          <q-card-actions class="q-px-md q-pb-md">
            <q-btn
              class="full-width"
              color="primary"
              no-caps
              padding="10px 16px"
              rounded
              unelevated
              :disable="addressLoading || !platformFeesReady || !hasSingleProvider"
              :label="$t('service_package.close')"
              :loading="submitting"
              @click="submitServicePackage"
            />
          </q-card-actions>
        </q-card>
      </div>
    </template>
  </q-page>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import { createScheduleServicePackage } from "src/api/servicePackage";
import { getAddresses } from "src/api/address";
import { getProfileMediaUrl } from "src/helpers/profileMedia";
import { useI18n } from "vue-i18n";
import { usePaymentPlatformFees } from "src/composables/usePaymentPlatformFees";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import { userStore } from "src/stores/user";
import { useServicePackageStore } from "src/stores/servicePackage";

const { t } = useI18n();
const router = useRouter();
const $q = useQuasar();
const { platformFees, loadPlatformFees } = usePaymentPlatformFees();

const servicePackage = useServicePackageStore();
const store = userStore();

const addressLoading = ref(false);
const primaryAddress = ref(null);
const submitting = ref(false);

const isValidFee = (fee) =>
  fee !== null && fee !== undefined && Number.isFinite(Number(fee));

const roundMoney = (value) => Number(Number(value ?? 0).toFixed(2));

const roundNullableMoney = (value) => {
  if (value === null || value === undefined || !Number.isFinite(Number(value)))
    return null;

  return roundMoney(value);
};

const sumItems = (callback) => {
  let total = 0;

  for (const item of servicePackage.items) {
    const itemTotal = callback(item);

    if (itemTotal === null) return null;

    total += itemTotal;
  }

  return total;
};

const getTotalWithFee = (item, fee) => {
  if (!isValidFee(fee)) return null;

  return roundMoney(Number(item.base_amount ?? 0) * (1 + Number(fee)));
};

const getServicePackageDiscountItemTotal = (item) =>
  getTotalWithFee(item, platformFees.value.service_package_min_3_schedules);

const getStandardPixItemTotal = (item) =>
  getTotalWithFee(item, platformFees.value.pix);

const servicePackageDiscountTotalAmount = computed(() =>
  roundNullableMoney(sumItems(getServicePackageDiscountItemTotal)),
);

const hasServicePackageDiscount = computed(() => servicePackage.items.length >= 3);

const missingSchedulesForDiscount = computed(() =>
  Math.max(3 - servicePackage.items.length, 0),
);

const servicePackageDiscountMessage = computed(() => {
  if (hasServicePackageDiscount.value) {
    return t("service_package.discount_applied");
  }

  return t("service_package.discount_hint", {
    count: missingSchedulesForDiscount.value,
  });
});

const platformFeesReady = computed(
  () =>
    isValidFee(platformFees.value.pix) &&
    isValidFee(platformFees.value.credit_card) &&
    (!hasServicePackageDiscount.value ||
      isValidFee(platformFees.value.service_package_min_3_schedules)),
);

const hasSingleProvider = computed(() => {
  const providers = new Set(
    servicePackage.items.map((item) => item.provider_id).filter(Boolean),
  );

  return providers.size <= 1;
});

const pixDiscountAmount = computed(() => {
  if (!hasServicePackageDiscount.value) return 0;

  return (
    roundNullableMoney(
      sumItems((item) => {
        const standardPixItemTotal = getStandardPixItemTotal(item);
        const discountedPixItemTotal = getServicePackageDiscountItemTotal(item);

        if (standardPixItemTotal === null || discountedPixItemTotal === null)
          return null;

        return standardPixItemTotal - discountedPixItemTotal;
      }),
    ) ?? 0
  );
});

const pixTotalAmount = computed(() =>
  roundNullableMoney(sumItems(getStandardPixItemTotal)),
);

const primaryAddressLabel = computed(() => {
  if (addressLoading.value) return t("service_package.loading");
  if (!primaryAddress.value) return t("service_package.no_primary_address");

  return [
    primaryAddress.value.address,
    primaryAddress.value.number,
    primaryAddress.value.district,
  ]
    .filter(Boolean)
    .join(", ");
});

const providerName = computed(() => {
  const providerNames = [
    ...new Set(servicePackage.items.map((item) => item.provider_name).filter(Boolean)),
  ];

  if (providerNames.length === 0) return t("service_package.unknown");
  if (providerNames.length === 1) return providerNames[0];

  return t("service_package.multiple_providers", { count: providerNames.length });
});

const normalizeDate = (value) =>
  String(value ?? "")
    .replace(/\//g, "-")
    .slice(0, 10);

const formatDate = (value) => {
  const parsed = new Date(`${normalizeDate(value)}T12:00:00`);

  return new Intl.DateTimeFormat("pt-BR", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
  }).format(parsed);
};

const formatPrice = (value) => {
  if (
    value === null ||
    value === undefined ||
    !Number.isFinite(Number(value))
  ) {
    return t("service_package.loading");
  }

  return Number(value ?? 0).toLocaleString("pt-BR", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
};

const formatCurrencyValue = (value) => {
  if (
    value === null ||
    value === undefined ||
    !Number.isFinite(Number(value))
  ) {
    return t("service_package.loading");
  }

  return t("service_package.currency_value", { value: formatPrice(value) });
};

const getCreditCardItemTotal = (item) =>
  getTotalWithFee(item, platformFees.value.credit_card);

const getProviderInitial = (item) =>
  item.provider_name?.slice(0, 1).toUpperCase() ??
  t("service_package.provider_initial");

const loadPrimaryAddress = async () => {
  const clientId = store.user?.client_id ?? store.user?.client?.id;

  if (!clientId) return;

  addressLoading.value = true;

  try {
    const addresses = await getAddresses("client", clientId);

    primaryAddress.value =
      (addresses ?? []).find((address) => address.is_primary) ?? null;
  } catch {
    primaryAddress.value = null;
  } finally {
    addressLoading.value = false;
  }
};

const submitServicePackage = async () => {
  if (!servicePackage.items.length || submitting.value) return;

  if (!hasSingleProvider.value) {
    $q.notify({
      type: "warning",
      message: t("service_package.same_provider_required"),
    });

    return;
  }

  if (!primaryAddress.value) {
    $q.notify({
      type: "warning",
      message: t("service_package.no_primary_address_notify"),
    });

    return;
  }

  const payload = {
    client_id: store.user.client_id ?? store.user?.client?.id,
    address_id: primaryAddress.value.id,
    schedule_type: "default",

    schedules: servicePackage.items.map((item) => ({
      provider_id: item.provider_id,
      date: item.date,
      period_type: item.period_type,
      start_time: item.start_time,
      end_time: item.end_time,
      total_amount: item.base_amount,
      offers_meal: item.offers_meal,
    })),
  };

  submitting.value = true;

  try {
    const createdServicePackage = await createScheduleServicePackage(payload);

    const createdSchedules = createdServicePackage?.schedules ?? [];

    const scheduleIds =
      createdServicePackage?.schedule_ids ??
      createdSchedules.map((schedule) => schedule.id);

    servicePackage.setLastCreatedGroup({
      local_group_id: createdServicePackage?.id ?? `sp-${Date.now()}`,
      service_package_id: createdServicePackage?.id ?? null,
      schedule_ids: scheduleIds,
      schedules: createdSchedules,
    });

    servicePackage.clear();

    $q.notify({
      type: "positive",
      message: t("service_package.closed_success"),
    });
  } catch (error) {
    const message =
      error?.response?.data?.message ??
      error?.message ??
      t("service_package.submit_error");

    $q.notify({ type: "negative", message });
  } finally {
    submitting.value = false;
  }
};

onMounted(() => {
  loadPrimaryAddress();
  loadPlatformFees().catch(() => {});
});
</script>

<style scoped lang="scss">
.service-package-page {
  min-height: 100%;
}

.shadow-service-package {
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);
}

.service-package-item-card,
.checkout-card,
.empty-card,
.created-card {
  border-radius: 8px;
}

.summary-row {
  border-top: 1px solid rgba(0, 0, 0, 0.05);
}

.item-prices {
  max-width: 220px;
}

.service-package-discount-banner {
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid rgba(34, 197, 94, 0.22);
  border-radius: 8px;
}

.summary-discount {
  background: rgba(34, 197, 94, 0.12);
  border-radius: 8px;
}
</style>
