<template>
  <q-page class="bg-page q-pb-xl">
    <div class="payments-header row items-center bg-white">
      <q-space />

      <span class="gradient-diarista font16 fontbold">
        {{ $t("provider.payments.title") }}
      </span>

      <q-space />
    </div>

    <div class="q-mx-md q-mt-md">
      <q-card
        class="earnings-card bg-primary"
        style="cursor: pointer"
        :flat="false"
        @click="earningsExpanded = !earningsExpanded"
      >
        <q-card-section class="q-pa-md">
          <div class="row items-center no-wrap">
            <q-icon
              class="q-mr-sm"
              color="white"
              name="mdi-currency-usd"
              size="22px"
            />

            <span class="text-white font16 fontbold">
              {{ $t("provider.payments.total_earnings_title") }}
            </span>

            <q-space />

            <q-icon
              color="white"
              size="22px"
              :name="
                earningsExpanded
                  ? 'mdi-chevron-up'
                  : 'mdi-chevron-down'
              "
            />
          </div>
        </q-card-section>

        <q-slide-transition>
          <div
            v-show="earningsExpanded"
            @click.stop
          >
            <q-separator
              color="white"
              style="opacity: 0.2"
            />

            <q-card-section class="q-pa-md">
              <div class="earnings-value font28 fontbold text-white">
                {{ formatCurrency(earningsByPeriod[selectedPeriod].value) }}
              </div>

              <div class="earnings-count font12 text-white q-mb-md">
                {{ $t("provider.payments.total_earnings_count", { count: earningsByPeriod[selectedPeriod].count }) }}
              </div>

              <div class="row q-gutter-x-xs q-mb-md">
                <q-btn
                  v-for="period in periods"
                  :key="period.key"
                  :color="
                    selectedPeriod === period.key
                      ? 'white'
                      : undefined
                  "
                  :flat="selectedPeriod !== period.key"
                  :label="$t(period.labelKey)"
                  :rounded="true"
                  :text-color="
                    selectedPeriod === period.key
                      ? 'primary'
                      : 'white'
                  "
                  :unelevated="selectedPeriod === period.key"
                  dense
                  no-caps
                  @click.stop="selectedPeriod = period.key"
                />
              </div>

              <div
                class="text-white font12"
                style="opacity: 0.8"
              >
                {{ $t("provider.payments.total_earnings_days", { days: periodDays[selectedPeriod] }) }}
              </div>
            </q-card-section>
          </div>
        </q-slide-transition>
      </q-card>
    </div>

    <div class="q-mx-md q-mt-md">
      <q-card
        class="balance-card bg-surface shadow-card"
        :flat="false"
      >
        <q-card-section class="q-pa-md">
          <div class="row items-center no-wrap q-mb-xs">
            <div class="col">
              <div class="text-grey-6 font12 fontbold">
                {{ $t("provider.payments.available_balance_label") }}
              </div>

              <div class="balance-value fontbold text-secondary">
                {{ formatCurrency(saldoDisponivel) }}
              </div>
            </div>

            <q-btn
              class="btn-withdraw font13 fontbold"
              color="secondary"
              no-caps
              unelevated
              :disable="!canWithdraw"
              :label="$t('provider.payments.btn_withdraw')"
              :loading="withdrawLoading"
              @click="onSacar"
            />
          </div>

          <div class="text-grey-6 font12">
            {{ $t("provider.payments.available_balance_prefix") }}

            <strong>
              {{ $t("provider.payments.available_balance_highlight") }}
            </strong>
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mx-md q-mt-md">
      <q-card
        class="balance-card bg-secondary shadow-card"
        :flat="false"
      >
        <q-card-section class="q-pa-md">
          <div class="row items-center no-wrap">
            <div class="col">
              <div class="text-white font12">
                {{ $t("provider.payments.pending_balance_label") }}
              </div>

              <div class="balance-value fontbold text-white">
                {{ formatCurrency(saldoALiberar) }}
              </div>

              <div
                class="text-white font12 q-mt-xs"
                style="opacity: 0.85"
              >
                {{ $t("provider.payments.pending_balance_desc") }}
              </div>
            </div>

            <q-icon
              color="white"
              name="mdi-clock-outline"
              size="32px"
              style="opacity: 0.7"
            />
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mx-md q-mt-lg">
      <div class="row items-center no-wrap q-mb-sm">
        <span class="section-title font16 fontbold gradient-diarista">
          {{ $t("provider.payments.services_title") }}
        </span>

        <q-space />

        <q-btn
          class="q-pr-none self-center"
          color="primary"
          flat
          icon-right="mdi-chevron-right"
          no-caps
          size="sm"
          :label="$t('provider.payments.btn_view_movements')"
          @click="openMovimentacoes"
        />
      </div>

      <div
        v-if="servicesLoading"
        class="flex flex-center q-py-xl"
      >
        <q-spinner
          color="primary"
          size="40px"
        />
      </div>

      <template
        v-for="item in services"
        :key="item.id"
      >
        <q-card
          class="service-card bg-surface shadow-card q-mb-sm"
          :flat="false"
        >
          <q-card-section class="q-pa-sm">
            <div class="row no-wrap items-start q-gutter-x-sm">
              <q-avatar size="44px">
                <img
                  v-if="item.client_photo"
                  :src="item.client_photo"
                  style="object-fit: cover"
                />

                <span
                  v-else
                  class="full-width full-height flex flex-center"
                  style="border-radius: 50%"
                  :style="avatarColors[item.id % avatarColors.length]"
                >
                  {{ item.client_name?.slice(0, 2).toUpperCase() ?? "??" }}
                </span>
              </q-avatar>

              <div class="col column">
                <span class="text-name font13 fontbold ellipsis">
                  {{ item.client_name }}
                </span>

                <div class="text-text fontmedium font12">
                  <span>
                    {{ $t("provider.payments.services_date_service") }}
                  </span>
                  {{ " " + item.date }}
                </div>

                <div class="text-text fontmedium font12">
                  <span>
                    {{ $t("provider.payments.services_date_payment") }}
                  </span>
                  {{ " " + item.payment_date }}
                </div>
              </div>

              <div class="col-auto column items-end">
                <q-chip
                  class="status-chip font11 fontbold"
                  dense
                  square
                  :color="payStatusBgColor(item.payment_status)"
                  :label="payStatusLabel(item.payment_status)"
                  :text-color="
                    payStatusTextColor(item.payment_status)
                  "
                />

                <span class="text-price font13 fontbold">
                  {{ formatCurrency(item.total_amount) }}
                </span>

                <span class="text-period font10">
                  {{ item.period_label }}
                </span>
              </div>
            </div>
          </q-card-section>
        </q-card>
      </template>
    </div>
  </q-page>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import { avatarColors, formatCurrency } from "src/helpers/utils";

import {
  getBalance,
  getWithdrawalFees,
  requestWithdrawal,
} from "src/api/providerWithdrawal";

import { getPaymentSplits } from "src/api/paymentSplit";
import { labelsPeriodTypes } from "src/helpers/labelsPeriodTypes.js";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";

import MovimentacoesDialog from "src/components/payments/MovimentacoesDialog.vue";
import WithdrawConfirmDialog from "src/components/payments/WithdrawConfirmDialog.vue";

const $q = useQuasar();

const { t } = useI18n();

const earningsExpanded = ref(false);
const selectedPeriod   = ref("week");
const servicesLoading  = ref(true);
const withdrawLoading  = ref(false);

const saldoDisponivel = ref(0);
const saldoALiberar   = ref(0);

const paymentTransferFeeAmount = ref(3.67);

const services = ref([]);

const earningsByPeriod = ref({
  week: {
    value: 0,
    count: 0,
  },
  month: {
    value: 0,
    count: 0,
  },
  year: {
    value: 0,
    count: 0,
  },
});

const withdrawalNetAmount = computed(() =>
  Math.max(
    0,
    roundMoney(
      saldoDisponivel.value - paymentTransferFeeAmount.value,
    ),
  ),
);

const canWithdraw = computed(
  () =>
    saldoDisponivel.value > 0 &&
    withdrawalNetAmount.value > 0 &&
    !withdrawLoading.value,
);



const periods = [
  {
    key: "week",
    labelKey: "provider.payments.period_week",
  },
  {
    key: "month",
    labelKey: "provider.payments.period_month",
  },
  {
    key: "year",
    labelKey: "provider.payments.period_year",
  },
];

const periodDays = {
  week: 7,
  month: 30,
  year: 365,
};

const loadData = async () => {
  servicesLoading.value = true;

  try {
    const [balance, splits, fees] = await Promise.all([
      getBalance(),
      getPaymentSplits(),
      loadWithdrawalFees(),
    ]);

    const paymentSplits = splits || [];

    const availableFromSplits = sumSplits(
      paymentSplits,
      isSplitAvailable,
    );

    const pendingFromSplits = sumSplits(
      paymentSplits,
      (split) =>
        isSplitPaidAndFinished(split) &&
        !isSplitAvailable(split),
    );

    saldoDisponivel.value =
      parseAmount(balance?.available) || availableFromSplits;

    saldoALiberar.value =
      parseAmount(balance?.pending) || pendingFromSplits;

    paymentTransferFeeAmount.value =
      parseAmount(
        fees?.payment_transfer_fee_amount ??
          fees?.gateway_fee_amount ??
          fees?.fee_amount ??
          fees?.amount,
      ) || paymentTransferFeeAmount.value;

    services.value = paymentSplits.map((split) => ({
      id: split.id,
      client_name:
        split.client_name ??
        t("provider.payments.default_client_name"),
      client_photo: null,
      date: formatServiceDate(split.schedule_date),
      payment_date: formatIsoDate(split.payment_paid_at),
      total_amount: splitAmount(split),
      period_label: split.schedule_period_type
        ? t(
            labelsPeriodTypes.find(
              (label) =>
                label.value == split.schedule_period_type,
            )?.label,
          )
        : "",
      schedule_type: "default",
      payment_status: splitPaymentStatus(split),
    }));
  } catch (error) {
    $q.notify({
      type: "negative",
      message:
        error?.response?.data?.message || error.message,
    });
  } finally {
    servicesLoading.value = false;
  }
};

const loadWithdrawalFees = async () => {
  try {
    return await getWithdrawalFees();
  } catch {
    return {
      payment_transfer_fee_amount:
        paymentTransferFeeAmount.value,
    };
  }
};

const onSacar = () => {
  const grossAmount = roundMoney(saldoDisponivel.value);

  const gatewayFeeAmount = roundMoney(
    paymentTransferFeeAmount.value,
  );

  const netAmount = roundMoney(withdrawalNetAmount.value);

  $q.dialog({
    component: WithdrawConfirmDialog,
    componentProps: {
      grossAmount,
      gatewayFeeAmount,
      netAmount,
    },
  }).onOk(async () => {
    withdrawLoading.value = true;

    try {
      await requestWithdrawal({
        gross_amount: grossAmount,
        gateway_fee_amount: gatewayFeeAmount,
        net_amount: netAmount,
      });

      saldoDisponivel.value = 0;
    } catch (error) {
      $q.notify({
        type: "negative",
        message:
          error?.response?.data?.message || error.message,
      });
    } finally {
      withdrawLoading.value = false;
    }
  });
};

const openMovimentacoes = () => {
  $q.dialog({
    component: MovimentacoesDialog,
  });
};

const parseAmount = (value) => {
  const amount = Number.parseFloat(value);

  return Number.isFinite(amount) ? amount : 0;
};

const roundMoney = (value) =>
  Math.round(
    (parseAmount(value) + Number.EPSILON) * 100,
  ) / 100;

const splitAmount = (split) =>
  parseAmount(
    split.provider_amount ??
      split.net_amount ??
      split.gross_amount,
  );

const splitPaymentStatus = (split) =>
  split.payment_status ??
  split.payment?.status ??
  "pending";

const splitScheduleStatus = (split) =>
  split.schedule_status ??
  split.schedule?.status ??
  split.scheduleStatus ??
  "";

const splitCodeVerified = (split) =>
  split.code_verified ??
  split.schedule?.code_verified ??
  false;

//

const isSplitAvailable = (split) => {
  if (!isSplitPaidAndFinished(split)) return false;

  const releaseAt = splitReleaseDate(split);

  if (!releaseAt) return true;

  const releaseDate = parseDateSafe(releaseAt);

  return !releaseDate || releaseDate <= new Date();
};

const isTruthyFlag = (value) =>
  value === true ||
  value === 1 ||
  value === "1" ||
  value === "true";

const isSplitPaidAndFinished = (split) =>
  splitPaymentStatus(split) === "paid" &&
  (!splitScheduleStatus(split) ||
    splitScheduleStatus(split) === "finished") &&
  isTruthyFlag(splitCodeVerified(split));

const splitReleaseDate = (split) =>
  split.available_at ??
  split.release_at ??
  split.released_at ??
  split.withdraw_available_at ??
  null;

const sumSplits = (splits, predicate) =>
  splits.reduce(
    (total, split) =>
      total +
      (predicate(split) ? splitAmount(split) : 0),
    0,
  );

//

const parseDateSafe = (value) => {
  if (!value) return null;

  const raw = String(value).trim();

  if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) {
    const date = new Date(`${raw}T12:00:00`);

    return Number.isNaN(date.getTime()) ? null : date;
  }

  const brDate = raw.match(
    /^(\d{2})\/(\d{2})\/(\d{4})$/,
  );

  if (brDate) {
    const [, day, month, year] = brDate;
    const date = new Date(
      `${year}-${month}-${day}T12:00:00`,
    );

    return Number.isNaN(date.getTime()) ? null : date;
  }

  const date = new Date(raw);

  return Number.isNaN(date.getTime()) ? null : date;
};


const formatShortDate = (dateString) => {
  const date = parseDateSafe(dateString);

  if (!date) return "";

  return date.toLocaleDateString("pt-BR", {
    day: "2-digit",
    month: "2-digit",
  });
};

const formatIsoDate = (dateString) =>
  formatShortDate(dateString);

const formatServiceDate = (dateString) =>
  formatShortDate(dateString);

//


const payStatusBgColor = (status) => {
  const colors = {
    pending: "warning-bg",
    paid: "success-bg",
    authorized: "teal-bg",
    processing: "info-bg",
    failed: "error-bg",
    cancelled: "neutral-bg",
  };

  return colors[status] ?? "neutral-bg";
};

const payStatusLabel = (status) => {
  const labels = {
    pending: t("provider.payments.pay_status_pending"),
    paid: t("provider.payments.pay_status_paid"),
    authorized: t(
      "provider.payments.pay_status_authorized",
    ),
    processing: t(
      "provider.payments.pay_status_processing",
    ),
    failed: t("provider.payments.pay_status_failed"),
    cancelled: t(
      "provider.payments.pay_status_cancelled",
    ),
  };

  return labels[status] ?? status;
};

const payStatusTextColor = (status) => {
  const colors = {
    pending: "warning",
    paid: "success",
    authorized: "teal",
    processing: "info",
    failed: "error-dark",
    cancelled: "status-finished",
  };

  return colors[status] ?? "text";
};

//

onMounted(loadData);
</script>

<style scoped lang="scss">
.payments-header {
  padding-top: 12px;
  padding-bottom: 12px;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08);
}

.earnings-card,
.balance-card,
.service-card {
  width: 100%;
  border-radius: 12px;
}

.earnings-value,
.balance-value {
  line-height: 1.2;
}

.earnings-count {
  opacity: 0.9;
}

.btn-withdraw {
  padding: 6px 18px;
  border-radius: 8px !important;
}

.text-name {
  max-width: 130px;
  overflow: hidden;
  color: #3a3a4a;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.text-price {
  color: #3a3a4a;
  white-space: nowrap;
}

.text-period {
  color: #888;
  text-align: right;
  white-space: nowrap;
}

.status-chip {
  height: auto;
  padding: 2px;
}
</style>
