<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" :flat="false" style="cursor: pointer;" @click="earningsExpanded = !earningsExpanded">
        <q-card-section class="q-pa-md">
          <div class="row items-center no-wrap">
            <q-icon name="mdi-currency-usd" size="22px" color="white" class="q-mr-sm" />
            <span class="text-white font16 fontbold">{{ $t('provider.payments.total_earnings_title') }}</span>
            <q-space />
            <q-icon
              :name="earningsExpanded ? 'mdi-chevron-up' : 'mdi-chevron-down'"
              size="22px"
              color="white"
            />
          </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"
                  dense
                  no-caps
                  :unelevated="selectedPeriod === period.key"
                  :flat="selectedPeriod !== period.key"
                  :rounded="true"
                  :color="selectedPeriod === period.key ? 'white' : undefined"
                  :text-color="selectedPeriod === period.key ? 'primary' : 'white'"
                  :label="$t(period.labelKey)"
                  @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-sm">
      <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
              unelevated
              no-caps
              color="secondary"
              class="btn-withdraw font13 fontbold"
              :label="$t('provider.payments.btn_withdraw')"
              :loading="withdrawLoading"
              :disable="!canWithdraw"
              @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-sm">
      <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 name="mdi-clock-outline" color="white" size="32px" style="opacity: 0.7;" />
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mx-md q-mt-md">
      <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
          flat
          no-caps
          color="primary"
          size="sm"
          :label="$t('provider.payments.btn_view_movements')"
          icon-right="mdi-chevron-right"
          @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="avatarColors[item.id % avatarColors.length]" style="border-radius:50%">{{ 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="">
                  <span class="">{{ $t('provider.payments.services_date_service') }}</span>
                  {{ ' ' + item.date }}
                </div>
                <div class="">
                  <span class="">{{ $t('provider.payments.services_date_payment') }}</span>
                  {{ ' ' + item.payment_date }}
                </div>
              </div>

              <div class="col-auto column items-end">
                <q-chip
                  dense
                  square
                  :color="payStatusBgColor(item.payment_status)"
                  :text-color="payStatusTextColor(item.payment_status)"
                  :label="payStatusLabel(item.payment_status)"
                  class="status-chip font11 fontbold"
                />
                <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, ref, onMounted } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { formatCurrency } from 'src/helpers/utils';
import { labelsPeriodTypes } from 'src/helpers/arraysOptions/labelsPeriodTypes.js';
import { getBalance, getWithdrawalFees, requestWithdrawal } from 'src/api/providerWithdrawal';
import { getPaymentSplits } from 'src/api/paymentSplit';
import MovimentacoesDialog from 'src/components/payments/MovimentacoesDialog.vue';
import WithdrawConfirmDialog from 'src/components/payments/WithdrawConfirmDialog.vue';

const $q = useQuasar();
const { t } = useI18n();

const avatarColors = [
  { background: '#ffd5df', color: '#932e57' },
  { background: '#d7e8ff', color: '#2158a8' },
  { background: '#dfd',    color: '#2a7a3b' },
  { background: '#ffe5cc', color: '#8a4500' },
];
const earningsExpanded = ref(false);
const selectedPeriod = ref('week');
const servicesLoading = ref(true);
const withdrawLoading = ref(false);

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 earningsByPeriod = ref({
  week:  { value: 0, count: 0 },
  month: { value: 0, count: 0 },
  year:  { value: 0, count: 0 },
});

const saldoDisponivel = ref(0);
const saldoALiberar = ref(0);
const paymentTransferFeeAmount = ref(3.67);
const services = ref([]);

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 withdrawalNetAmount = computed(() => (
  Math.max(0, roundMoney(saldoDisponivel.value - paymentTransferFeeAmount.value))
));

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

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 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 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 sumSplits = (splits, predicate) => (
  splits.reduce((total, split) => total + (predicate(split) ? splitAmount(split) : 0), 0)
);

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((s) => ({
      id: s.id,
      client_name: s.client_name ?? t('provider.payments.default_client_name'),
      client_photo: null,
      date: formatServiceDate(s.schedule_date),
      payment_date: formatIsoDate(s.payment_paid_at),
      total_amount: splitAmount(s),
      period_label: s.schedule_period_type
        ? t(labelsPeriodTypes.find(l => l.value == s.schedule_period_type)?.label)
        : '',
      schedule_type: 'default',
      payment_status: splitPaymentStatus(s),
    }));
  } 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;
      // notification handled by axios interceptor
    } catch (error) {
      $q.notify({ type: 'negative', message: error?.response?.data?.message || error.message });
    } finally {
      withdrawLoading.value = false;
    }
  });
};

const parseDateSafe = (value) => {
  if (!value) return null;
  const raw = String(value).trim();

  // yyyy-mm-dd (from API date fields)
  if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) {
    const date = new Date(`${raw}T12:00:00`);
    return Number.isNaN(date.getTime()) ? null : date;
  }

  // dd/mm/yyyy
  const brMatch = raw.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  if (brMatch) {
    const [, day, month, year] = brMatch;
    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 = (dateStr) => {
  const date = parseDateSafe(dateStr);
  if (!date) return '';
  return date.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' });
};

const formatServiceDate = (dateStr) => formatShortDate(dateStr);
const formatIsoDate = (dateStr) => formatShortDate(dateStr);

const payStatusLabel = (status) => {
  const map = {
    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 map[status] ?? status;
};

const payStatusBgColor = (status) => {
  const map = {
    pending:    'warning-bg',
    paid:       'success-bg',
    authorized: 'teal-bg',
    processing: 'info-bg',
    failed:     'error-bg',
    cancelled:  'neutral-bg',
  };
  return map[status] ?? 'neutral-bg';
};

const payStatusTextColor = (status) => {
  const map = {
    pending:    'warning',
    paid:       'success',
    authorized: 'teal',
    processing: 'info',
    failed:     'error-dark',
    cancelled:  'status-finished',
  };
  return map[status] ?? 'text';
};

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

onMounted(() => {
  loadData();
});
</script>

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

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

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

.earnings-count {
  opacity: 0.9;
}

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

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

.text-name {
  color: #3a3a4a;
  max-width: 130px;
  overflow: hidden;
  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 2px;
}
</style>
