<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/components/agenda/AgendaEventoFinanceiroPanel.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->

<!--
  AgendaEventoFinanceiroPanel
  ───────────────────────────
  Painel compacto de status financeiro exibido dentro do modal de sessão.
  Mostra o financial_record vinculado ao evento e permite registrar pagamento
  ou gerar cobrança sem sair do contexto da agenda.

  Props:
    evento  — linha de agenda_eventos (deve ter: id, tipo, billed,
              billing_contract_id, price, patient_id, inicio_em)

  Emits:
    cobranca-atualizada — após qualquer mutação, para o pai recarregar
-->
<script setup>
import { ref, computed, watch } from 'vue'
import { useToast }   from 'primevue/usetoast'
import { useConfirm } from 'primevue/useconfirm'

import { supabase }              from '@/lib/supabase/client'
import { useAgendaFinanceiro }   from '@/composables/useAgendaFinanceiro'

// ── props / emits ─────────────────────────────────────────────────────────────
const props = defineProps({
  evento: {
    type:     Object,
    required: true,
  },
})

const emit = defineEmits(['cobranca-atualizada'])

// ── external ──────────────────────────────────────────────────────────────────
const toast   = useToast()
const confirm = useConfirm()
const { gerarCobrancaManual, loading: finLoading, error: finError } = useAgendaFinanceiro()

// ── estado local ──────────────────────────────────────────────────────────────
const record     = ref(null)   // financial_record vinculado
const fetching   = ref(false)
const generating = ref(false)

// ── opções de método de pagamento ─────────────────────────────────────────────
const PAYMENT_METHODS = [
  { label: 'Pix',      value: 'pix' },
  { label: 'Depósito', value: 'deposito' },
  { label: 'Dinheiro', value: 'dinheiro' },
  { label: 'Cartão',   value: 'cartao' },
  { label: 'Convênio', value: 'convenio' },
]

function paymentLabel (method) {
  return PAYMENT_METHODS.find(o => o.value === method)?.label ?? method ?? '—'
}

// ── formatação ─────────────────────────────────────────────────────────────────
const _brl = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' })
function fmtBRL  (v)   { return _brl.format(v ?? 0) }
function fmtDate (iso) {
  if (!iso) return '—'
  const d = iso.includes('T') ? new Date(iso) : new Date(iso + 'T00:00:00')
  return new Intl.DateTimeFormat('pt-BR').format(d)
}

// ── config visual de status ────────────────────────────────────────────────────
const STATUS_CFG = {
  pending:   { label: 'Pendente',  severity: 'warn' },
  paid:      { label: 'Pago',      severity: 'success' },
  overdue:   { label: 'Vencido',   severity: 'danger' },
  cancelled: { label: 'Cancelado', severity: 'secondary' },
}

// ── computed: cenário a renderizar ────────────────────────────────────────────
const scenario = computed(() => {
  if (props.evento.tipo !== 'sessao')   return 'noop'      // bloqueio
  if (props.evento.billing_contract_id) return 'contrato'  // pacote
  if (fetching.value)                   return 'carregando'
  if (record.value)                     return 'com-cobranca'
  return 'sem-cobranca'
})

const canAct = computed(() =>
  record.value && (record.value.status === 'pending' || record.value.status === 'overdue')
)

// ── buscar financial_record pelo evento ───────────────────────────────────────
async function fetchRecord () {
  if (!props.evento.id) return

  fetching.value = true
  try {
    const { data, error } = await supabase
      .from('financial_records')
      .select('id, amount, discount_amount, final_amount, status, due_date, paid_at, payment_method')
      .eq('agenda_evento_id', props.evento.id)
      .order('created_at', { ascending: false })
      .limit(1)
      .maybeSingle()

    if (error) throw error
    record.value = data ?? null
  } catch (e) {
    console.warn('[AgendaEventoFinanceiroPanel] fetchRecord:', e?.message)
    record.value = null
  } finally {
    fetching.value = false
  }
}

watch(() => props.evento?.id, () => {
  record.value = null
  fetchRecord()
}, { immediate: true })

// ── gerar cobrança ─────────────────────────────────────────────────────────────
async function onGerarCobranca () {
  generating.value = true
  try {
    const result = await gerarCobrancaManual(props.evento)
    if (!result.ok) throw new Error(result.error)

    await fetchRecord()
    emit('cobranca-atualizada')
    toast.add({ severity: 'success', summary: 'Cobrança gerada', detail: `${fmtBRL(props.evento.price ?? 0)} agendado para recebimento.`, life: 3000 })
  } catch (e) {
    toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Não foi possível gerar a cobrança.', life: 4000 })
  } finally {
    generating.value = false
  }
}

// ── dialog: registrar pagamento ───────────────────────────────────────────────
const payDlgVisible  = ref(false)
const payDlgMethod   = ref(null)
const payDlgLoading  = ref(false)

function openPayDialog () {
  payDlgMethod.value  = null
  payDlgVisible.value = true
}

async function confirmPayment () {
  if (!payDlgMethod.value || !record.value) return
  payDlgLoading.value = true
  try {
    const { data, error } = await supabase.rpc('mark_as_paid', {
      p_financial_record_id: record.value.id,
      p_payment_method:      payDlgMethod.value,
    })
    if (error) throw error

    payDlgVisible.value = false
    await fetchRecord()
    emit('cobranca-atualizada')
    toast.add({ severity: 'success', summary: 'Pago!', detail: `Recebimento via ${paymentLabel(payDlgMethod.value)} registrado.`, life: 3000 })
  } catch (e) {
    toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Não foi possível registrar pagamento.', life: 4000 })
  } finally {
    payDlgLoading.value = false
  }
}

// ── cancelar cobrança ─────────────────────────────────────────────────────────
function requestCancel () {
  confirm.require({
    message: `Cancelar a cobrança de ${fmtBRL(record.value?.final_amount)} desta sessão?`,
    header: 'Cancelar cobrança',
    icon: 'pi pi-exclamation-triangle',
    rejectLabel: 'Não',
    acceptLabel: 'Sim, cancelar',
    acceptSeverity: 'danger',
    accept: async () => {
      try {
        const { error } = await supabase
          .from('financial_records')
          .update({ status: 'cancelled', updated_at: new Date().toISOString() })
          .eq('id', record.value.id)

        if (error) throw error

        await fetchRecord()
        emit('cobranca-atualizada')
        toast.add({ severity: 'info', summary: 'Cancelado', detail: 'Cobrança cancelada.', life: 3000 })
      } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Falha ao cancelar.', life: 4000 })
      }
    },
  })
}
</script>

<template>
  <div>
  <!-- Painel principal — noop (bloqueios) não renderiza nada -->
  <div v-if="scenario !== 'noop'" class="fin-panel">

    <!-- Cabeçalho do painel -->
    <div class="fin-panel__header">
      <i class="pi pi-wallet" />
      <span>Cobrança</span>
      <Button
        v-if="props.evento.billed && !fetching"
        icon="pi pi-refresh"
        text
        size="small"
        severity="secondary"
        class="ml-auto h-6 w-6"
        v-tooltip.top="'Recarregar'"
        @click="fetchRecord"
      />
    </div>

    <!-- ── Sessão de pacote / contrato ──────────────────────────────────── -->
    <div v-if="scenario === 'contrato'" class="fin-panel__body">
      <span class="fin-badge fin-badge--contract">
        <i class="pi pi-box text-xs" />
        Sessão de pacote
      </span>
    </div>

    <!-- ── Sem cobrança gerada ──────────────────────────────────────────── -->
    <div v-else-if="scenario === 'sem-cobranca'" class="fin-panel__body fin-panel__body--empty">
      <div class="flex items-center gap-2 text-[var(--text-color-secondary)]">
        <i class="pi pi-minus-circle text-sm opacity-50" />
        <span class="text-sm">Sem cobrança gerada</span>
      </div>
      <Button
        label="Gerar cobrança"
        icon="pi pi-plus"
        size="small"
        class="rounded-full mt-2"
        :loading="generating || finLoading"
        @click="onGerarCobranca"
      />
      <div v-if="props.evento.price" class="text-xs text-[var(--text-color-secondary)] mt-1">
        Valor da sessão: {{ fmtBRL(props.evento.price) }}
      </div>
    </div>

    <!-- ── Carregando o financial_record ────────────────────────────────── -->
    <div v-else-if="scenario === 'carregando'" class="fin-panel__body">
      <div class="flex flex-col gap-1.5">
        <Skeleton height="1rem" class="w-24" />
        <Skeleton height="1.5rem" class="w-32" />
        <Skeleton height="1rem" class="w-20" />
      </div>
    </div>

    <!-- ── Com cobrança ─────────────────────────────────────────────────── -->
    <div v-else-if="scenario === 'com-cobranca'" class="fin-panel__body">

      <!-- Linha de status + valor -->
      <div class="flex items-center justify-between gap-2">
        <Tag
          :value="STATUS_CFG[record.status]?.label ?? record.status"
          :severity="STATUS_CFG[record.status]?.severity"
          class="text-xs"
        />
        <span class="font-bold text-sm text-[var(--text-color)]">{{ fmtBRL(record.final_amount) }}</span>
      </div>

      <!-- Vencimento / data de pagamento -->
      <div class="flex items-center gap-1.5 text-xs text-[var(--text-color-secondary)] mt-1.5">
        <template v-if="record.status === 'paid'">
          <i class="pi pi-check-circle text-emerald-500" />
          <span class="text-emerald-600">{{ paymentLabel(record.payment_method) }} · {{ fmtDate(record.paid_at) }}</span>
        </template>
        <template v-else>
          <i class="pi pi-calendar" />
          <span :class="record.status === 'overdue' ? 'text-red-500 font-semibold' : ''">
            Vence {{ fmtDate(record.due_date) }}
          </span>
        </template>
      </div>

      <!-- Ações: pendente / vencido -->
      <div v-if="canAct" class="flex gap-1.5 mt-3">
        <Button
          label="Receber"
          icon="pi pi-check"
          size="small"
          class="rounded-full flex-1"
          @click="openPayDialog"
        />
        <Button
          icon="pi pi-times"
          size="small"
          severity="danger"
          outlined
          class="rounded-full h-7 w-7"
          v-tooltip.top="'Cancelar cobrança'"
          @click="requestCancel"
        />
      </div>

    </div>

  </div>

  <!-- ── Dialog: Registrar Pagamento ──────────────────────────────────────── -->
  <Dialog
    v-model:visible="payDlgVisible"
    modal
    :draggable="false"
    pt:mask:class="backdrop-blur-xs"
    header="Registrar pagamento"
    class="w-[92vw] max-w-sm"
  >
    <div class="flex flex-col gap-4 pt-1">

      <!-- Valor -->
      <div class="flex items-center justify-between px-4 py-2.5 rounded-md border border-[var(--surface-border)] bg-[var(--surface-ground)]">
        <span class="text-sm text-[var(--text-color-secondary)]">Valor a receber</span>
        <span class="font-bold text-[var(--text-color)]">{{ fmtBRL(record?.final_amount) }}</span>
      </div>

      <!-- Método (grid de botões) -->
      <div>
        <div class="text-sm font-semibold text-[var(--text-color)] mb-2">Método de pagamento</div>
        <div class="grid grid-cols-3 gap-2">
          <button
            v-for="opt in PAYMENT_METHODS"
            :key="opt.value"
            type="button"
            class="flex flex-col items-center gap-1 px-2 py-2 rounded-md border text-xs font-medium transition-all duration-150 cursor-pointer select-none"
            :class="payDlgMethod === opt.value
              ? 'border-[var(--primary-color,#6366f1)] bg-[var(--primary-color,#6366f1)]/10 text-[var(--primary-color,#6366f1)]'
              : 'border-[var(--surface-border)] bg-[var(--surface-ground)] text-[var(--text-color-secondary)] hover:border-[var(--primary-color,#6366f1)]/40'"
            @click="payDlgMethod = opt.value"
          >
            <i
              class="text-base"
              :class="{
                'pi pi-bolt':        opt.value === 'pix',
                'pi pi-building':    opt.value === 'deposito',
                'pi pi-money-bill':  opt.value === 'dinheiro',
                'pi pi-credit-card': opt.value === 'cartao',
                'pi pi-id-card':     opt.value === 'convenio',
              }"
            />
            {{ opt.label }}
          </button>
        </div>
      </div>
    </div>

    <template #footer>
      <Button label="Cancelar" severity="secondary" outlined class="rounded-full" :disabled="payDlgLoading" @click="payDlgVisible = false" />
      <Button label="Confirmar" icon="pi pi-check" class="rounded-full" :loading="payDlgLoading" :disabled="!payDlgMethod" @click="confirmPayment" />
    </template>
  </Dialog>
  </div>
</template>

<style scoped>
.fin-panel {
  border: 1px solid var(--surface-border, #e2e8f0);
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--surface-card, #fff);
}

.fin-panel__header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--surface-ground, #f8fafc);
  border-bottom: 1px solid var(--surface-border, #e2e8f0);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-color-secondary);
}

.fin-panel__body {
  padding: 0.75rem;
}

.fin-panel__body--empty {
  display: flex;
  flex-direction: column;
}

.fin-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.25rem 0.625rem;
  border-radius: 9999px;
}

.fin-badge--contract {
  background: color-mix(in srgb, var(--p-indigo-500, #6366f1) 10%, transparent);
  color: var(--p-indigo-600, #4f46e5);
  border: 1px solid color-mix(in srgb, var(--p-indigo-500, #6366f1) 20%, transparent);
}
</style>
