<!-- src/views/pages/billing/ClinicMeuPlanoPage.vue -->
<script setup>
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import { useToast } from 'primevue/usetoast'

import { supabase } from '@/lib/supabase/client'
import { useTenantStore } from '@/stores/tenantStore'

const router = useRouter()
const route = useRoute()
const toast = useToast()
const tenantStore = useTenantStore()

const loading = ref(false)

const subscription = ref(null)
const plan = ref(null)
const price = ref(null)

const features = ref([]) // [{ key, description }]
const events = ref([]) // subscription_events

// ✅ para histórico auditável
const plans = ref([]) // [{id,key,name}]
const profiles = ref([]) // profiles de created_by

const tenantId = computed(() =>
  tenantStore.activeTenantId || tenantStore.tenantId || tenantStore.currentTenantId || null
)

// -------------------------
// helpers (format)
// -------------------------
function money (currency, amountCents) {
  if (amountCents == null) return null
  const value = Number(amountCents) / 100
  try {
    return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: currency || 'BRL' }).format(value)
  } catch (_) {
    return `${value.toFixed(2)} ${currency || ''}`.trim()
  }
}

function goUpgradeClinic () {
  // ✅ mantém caminho de retorno consistente
  const redirectTo = route?.fullPath || '/admin/meu-plano'
  router.push(`/upgrade?redirectTo=${encodeURIComponent(redirectTo)}`)
}

function fmtDate (iso) {
  if (!iso) return '-'
  const d = new Date(iso)
  if (Number.isNaN(d.getTime())) return String(iso)
  return d.toLocaleString('pt-BR')
}

function prettyMeta (meta) {
  if (!meta) return null
  try {
    if (typeof meta === 'string') return meta
    return JSON.stringify(meta, null, 2)
  } catch (_) {
    return String(meta)
  }
}

function statusSeverity (st) {
  const s = String(st || '').toLowerCase()
  if (s === 'active') return 'success'
  if (s === 'trialing') return 'info'
  if (s === 'past_due') return 'warning'
  if (s === 'canceled' || s === 'cancelled') return 'danger'
  if (s === 'incomplete' || s === 'incomplete_expired' || s === 'unpaid') return 'warning'
  return 'secondary'
}

function statusLabelPretty (st) {
  const s = String(st || '').toLowerCase()
  if (s === 'active') return 'Ativa'
  if (s === 'trialing') return 'Trial'
  if (s === 'past_due') return 'Pagamento pendente'
  if (s === 'canceled' || s === 'cancelled') return 'Cancelada'
  if (s === 'unpaid') return 'Não paga'
  if (s === 'incomplete') return 'Incompleta'
  if (s === 'incomplete_expired') return 'Incompleta (expirada)'
  return st || '-'
}

function eventSeverity (t) {
  const k = String(t || '').toLowerCase()
  if (k === 'plan_changed') return 'info'
  if (k === 'canceled') return 'danger'
  if (k === 'reactivated') return 'success'
  if (k === 'created') return 'secondary'
  if (k === 'status_changed') return 'warning'
  return 'secondary'
}

function eventLabel (t) {
  const k = String(t || '').toLowerCase()
  if (k === 'plan_changed') return 'Plano alterado'
  if (k === 'canceled') return 'Cancelada'
  if (k === 'reactivated') return 'Reativada'
  if (k === 'created') return 'Criada'
  if (k === 'status_changed') return 'Status alterado'
  return t || '-'
}

// -------------------------
// helpers (plans / profiles)
// -------------------------
const planById = computed(() => {
  const m = new Map()
  for (const p of plans.value || []) m.set(String(p.id), p)
  return m
})

function planKeyOrName (planId) {
  if (!planId) return '—'
  const p = planById.value.get(String(planId))
  return p?.key || p?.name || String(planId)
}

const profileById = computed(() => {
  const m = new Map()
  for (const p of profiles.value || []) m.set(String(p.id), p)
  return m
})

function displayUser (userId) {
  if (!userId) return '—'
  const p = profileById.value.get(String(userId))
  if (!p) return String(userId)

  const name = p.nome || p.name || p.full_name || p.display_name || p.username || null
  const email = p.email || p.email_principal || p.user_email || null

  if (name && email) return `${name} <${email}>`
  if (name) return name
  if (email) return email
  return String(userId)
}

// -------------------------
// computed (header info)
// -------------------------
const planName = computed(() => plan.value?.name || subscription.value?.plan_key || '-')
const statusLabel = computed(() => subscription.value?.status || '-')
const statusLabelPrettyComputed = computed(() => statusLabelPretty(subscription.value?.status))

const intervalLabel = computed(() => {
  const i = subscription.value?.interval
  if (i === 'month') return 'mês'
  if (i === 'year') return 'ano'
  return i || '-'
})

const priceLabel = computed(() => {
  if (!price.value) return null
  return `${money(price.value.currency, price.value.amount_cents)} / ${intervalLabel.value}`
})

const periodLabel = computed(() => {
  const s = subscription.value
  if (!s?.current_period_start || !s?.current_period_end) return '-'
  return `${fmtDate(s.current_period_start)} → ${fmtDate(s.current_period_end)}`
})

const cancelHint = computed(() => {
  const s = subscription.value
  if (!s) return null
  if (s.cancel_at_period_end) {
    const end = s.current_period_end ? fmtDate(s.current_period_end) : null
    return end ? `Cancelamento no fim do período (${end}).` : 'Cancelamento no fim do período.'
  }
  if (s.canceled_at) return `Cancelada em ${fmtDate(s.canceled_at)}.`
  return null
})

// -------------------------
// ✅ agrupamento de features por módulo (prefixo)
// -------------------------
function moduleFromKey (key) {
  const k = String(key || '').trim()
  if (!k) return 'Outros'

  // tenta por "."
  if (k.includes('.')) {
    const head = k.split('.')[0]
    return head || 'Outros'
  }

  // tenta por "_"
  if (k.includes('_')) {
    const head = k.split('_')[0]
    return head || 'Outros'
  }

  return 'Outros'
}

function moduleLabel (m) {
  const s = String(m || '').trim()
  if (!s) return 'Outros'
  return s.charAt(0).toUpperCase() + s.slice(1)
}

const groupedFeatures = computed(() => {
  const list = features.value || []
  const map = new Map()

  for (const f of list) {
    const mod = moduleFromKey(f.key)
    if (!map.has(mod)) map.set(mod, [])
    map.get(mod).push(f)
  }

  // ordena módulos e itens
  const modules = Array.from(map.keys()).sort((a, b) => {
    if (a === 'Outros') return 1
    if (b === 'Outros') return -1
    return a.localeCompare(b)
  })

  return modules.map(mod => {
    const items = map.get(mod) || []
    items.sort((a, b) => String(a.key || '').localeCompare(String(b.key || '')))
    return { module: mod, items }
  })
})

// -------------------------
// fetch
// -------------------------
async function fetchMeuPlanoClinic () {
  loading.value = true
  try {
    const tid = tenantId.value
    if (!tid) throw new Error('Tenant ativo não encontrado.')

    // 1) assinatura do tenant (prioriza status "ativo" e afins; cai pro mais recente)
    // ✅ depois das mudanças: não assume só "active" (pode estar trialing/past_due etc.)
    const sRes = await supabase
      .from('subscriptions')
      .select('*')
      .eq('tenant_id', tid)
      .order('created_at', { ascending: false })
      .limit(10)

    if (sRes.error) throw sRes.error

    const list = sRes.data || []
    const priority = (st) => {
      const s = String(st || '').toLowerCase()
      if (s === 'active') return 1
      if (s === 'trialing') return 2
      if (s === 'past_due') return 3
      if (s === 'unpaid') return 4
      if (s === 'incomplete') return 5
      if (s === 'canceled' || s === 'cancelled') return 9
      return 8
    }

    subscription.value = (list.slice().sort((a, b) => {
      const pa = priority(a?.status)
      const pb = priority(b?.status)
      if (pa !== pb) return pa - pb
      // empate: mais recente
      return new Date(b?.created_at || 0) - new Date(a?.created_at || 0)
    })[0]) || null

    if (!subscription.value) {
      plan.value = null
      price.value = null
      features.value = []
      events.value = []
      plans.value = []
      profiles.value = []
      return
    }

    // 2) plano (atual)
    if (subscription.value.plan_id) {
      const pRes = await supabase
        .from('plans')
        .select('id, key, name, description')
        .eq('id', subscription.value.plan_id)
        .maybeSingle()

      if (pRes.error) throw pRes.error
      plan.value = pRes.data || null
    } else {
      plan.value = null
    }

    // 3) preço vigente (intervalo atual)
    // ✅ robustez: tenta preço vigente por janela; se não achar, pega o último ativo do intervalo
    price.value = null
    if (subscription.value.plan_id && subscription.value.interval) {
      const nowIso = new Date().toISOString()

      const ppRes = await supabase
        .from('plan_prices')
        .select('currency, interval, amount_cents, is_active, active_from, active_to')
        .eq('plan_id', subscription.value.plan_id)
        .eq('interval', subscription.value.interval)
        .eq('is_active', true)
        .lte('active_from', nowIso)
        .or(`active_to.is.null,active_to.gte.${nowIso}`)
        .order('active_from', { ascending: false })
        .limit(1)
        .maybeSingle()

      if (ppRes.error) throw ppRes.error
      price.value = ppRes.data || null

      if (!price.value) {
        const ppFallback = await supabase
          .from('plan_prices')
          .select('currency, interval, amount_cents, is_active, active_from, active_to')
          .eq('plan_id', subscription.value.plan_id)
          .eq('interval', subscription.value.interval)
          .eq('is_active', true)
          .order('active_from', { ascending: false })
          .limit(1)
          .maybeSingle()

        if (ppFallback.error) throw ppFallback.error
        price.value = ppFallback.data || null
      }
    }

    // 4) features do plano
    features.value = []
    if (subscription.value.plan_id) {
      const pfRes = await supabase
        .from('plan_features')
        .select('feature_id')
        .eq('plan_id', subscription.value.plan_id)

      if (pfRes.error) throw pfRes.error

      const featureIds = (pfRes.data || []).map(r => r.feature_id).filter(Boolean)
      if (featureIds.length) {
        const fRes = await supabase
          .from('features')
          .select('id, key, description, descricao')
          .in('id', featureIds)
          .order('key', { ascending: true })

        if (fRes.error) throw fRes.error

        features.value = (fRes.data || []).map(f => ({
          key: f.key,
          description: (f.descricao || f.description || '').trim()
        }))
      }
    }

    // 5) histórico (50) — se existir subscription_id
    events.value = []
    if (subscription.value?.id) {
      const eRes = await supabase
        .from('subscription_events')
        .select('*')
        .eq('subscription_id', subscription.value.id)
        .order('created_at', { ascending: false })
        .limit(50)

      if (eRes.error) throw eRes.error
      events.value = eRes.data || []
    }

    // ✅ 6) pré-carrega planos citados em (old/new) + plano atual
    const planIds = new Set()
    if (subscription.value?.plan_id) planIds.add(String(subscription.value.plan_id))

    for (const ev of events.value) {
      if (ev?.old_plan_id) planIds.add(String(ev.old_plan_id))
      if (ev?.new_plan_id) planIds.add(String(ev.new_plan_id))
    }

    if (planIds.size) {
      const { data: pAll, error: epAll } = await supabase
        .from('plans')
        .select('id,key,name')
        .in('id', Array.from(planIds))

      plans.value = epAll ? [] : (pAll || [])
    } else {
      plans.value = []
    }

    // ✅ 7) perfis (created_by)
    const userIds = new Set()
    for (const ev of events.value) {
      const by = String(ev.created_by || '').trim()
      if (by) userIds.add(by)
    }

    if (userIds.size) {
      const { data: pr, error: epr } = await supabase
        .from('profiles')
        .select('*')
        .in('id', Array.from(userIds))

      profiles.value = epr ? [] : (pr || [])
    } else {
      profiles.value = []
    }
  } catch (e) {
    console.error(e)
    toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || String(e), life: 5000 })
  } finally {
    loading.value = false
  }
}

onMounted(fetchMeuPlanoClinic)
</script>

<template>
  <div class="p-4 md:p-6">
    <Toast />

    <!-- Topbar padrão -->
    <div class="mb-4 rounded-3xl border border-[var(--surface-border)] bg-[var(--surface-card)] p-4 shadow-sm">
      <div class="flex flex-wrap items-center justify-between gap-3">
        <div class="flex flex-col">
          <div class="text-2xl font-semibold leading-none">Meu plano</div>
          <small class="text-color-secondary mt-1">
            Plano da clínica (tenant) e recursos habilitados.
          </small>
        </div>

        <div class="flex items-center gap-2 flex-wrap justify-end">
          <Button
            label="Alterar plano"
            icon="pi pi-arrow-up-right"
            :loading="loading"
            @click="goUpgradeClinic"
          />
          <Button
            label="Atualizar"
            icon="pi pi-refresh"
            severity="secondary"
            outlined
            :loading="loading"
            @click="fetchMeuPlanoClinic"
          />
        </div>
      </div>
    </div>

    <!-- Card resumo -->
    <Card class="rounded-[2rem] overflow-hidden">
      <template #content>
        <div class="flex flex-wrap items-start justify-between gap-4">
          <div class="min-w-0">
            <div class="text-xl md:text-2xl font-semibold leading-tight">
              {{ planName }}
            </div>

            <div class="text-sm text-color-secondary mt-1">
              <span v-if="priceLabel">{{ priceLabel }}</span>
              <span v-else>Preço não encontrado para este intervalo.</span>
            </div>

            <div class="mt-3 flex flex-wrap gap-2">
              <Tag :value="statusLabelPrettyComputed" :severity="statusSeverity(subscription?.status)" />
              <Tag
                v-if="subscription?.cancel_at_period_end"
                severity="warning"
                value="Cancelamento agendado"
                rounded
              />
              <Tag
                v-else-if="subscription"
                severity="success"
                value="Renovação automática"
                rounded
              />
            </div>

            <div class="mt-3 text-sm text-color-secondary">
              <b>Período:</b> {{ periodLabel }}
            </div>

            <div v-if="cancelHint" class="mt-2 text-sm text-color-secondary">
              {{ cancelHint }}
            </div>

            <div v-if="plan?.description" class="mt-3 text-sm opacity-80 max-w-3xl">
              {{ plan.description }}
            </div>
          </div>

          <div v-if="subscription" class="flex flex-col items-end gap-2">
            <small class="text-color-secondary">subscription_id</small>
            <code class="text-xs opacity-80 break-all">
              {{ subscription.id }}
            </code>
          </div>
        </div>

        <div v-if="!subscription" class="mt-4 rounded-2xl border border-[var(--surface-border)] p-4 text-sm text-color-secondary">
          Nenhuma assinatura encontrada para este tenant.
        </div>
      </template>
    </Card>

    <Divider class="my-6" />

    <div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
      <!-- ✅ Features agrupadas -->
      <Card class="rounded-[2rem] overflow-hidden">
        <template #title>Seu plano inclui</template>
        <template #content>
          <div v-if="!subscription" class="text-color-secondary">
            Sem assinatura.
          </div>

          <div v-else-if="!features.length" class="text-color-secondary">
            Nenhuma feature vinculada a este plano.
          </div>

          <div v-else class="space-y-5">
            <div
              v-for="g in groupedFeatures"
              :key="g.module"
              class="rounded-2xl border border-[var(--surface-border)] overflow-hidden"
            >
              <div class="px-4 py-3 bg-[var(--surface-50)] border-b border-[var(--surface-border)] flex items-center justify-between">
                <div class="font-semibold">
                  {{ moduleLabel(g.module) }}
                </div>
                <Tag :value="`${g.items.length}`" severity="secondary" rounded />
              </div>

              <div class="p-4">
                <ul class="m-0 p-0 list-none space-y-3">
                  <li
                    v-for="f in g.items"
                    :key="f.key"
                    class="rounded-2xl border border-[var(--surface-border)] p-3"
                  >
                    <div class="flex items-start gap-3">
                      <i class="pi pi-check mt-1 text-sm text-color-secondary"></i>
                      <div class="min-w-0">
                        <div class="font-medium break-words">{{ f.key }}</div>
                        <div class="text-sm text-color-secondary mt-1" v-if="f.description">
                          {{ f.description }}
                        </div>
                      </div>
                    </div>
                  </li>
                </ul>
              </div>
            </div>

            <div class="text-xs text-color-secondary">
              Agrupamento automático por prefixo da key (ex.: <b>agenda.*</b>, <b>patients.*</b>, etc.).
            </div>
          </div>
        </template>
      </Card>

      <!-- ✅ Histórico auditável -->
      <Card class="rounded-[2rem] overflow-hidden">
        <template #title>Histórico</template>
        <template #content>
          <div v-if="!subscription" class="text-color-secondary">
            Sem histórico (não há assinatura).
          </div>

          <div v-else-if="!events.length" class="text-color-secondary">
            Sem eventos registrados.
          </div>

          <div v-else class="space-y-3">
            <div
              v-for="ev in events"
              :key="ev.id"
              class="rounded-2xl border border-[var(--surface-border)] p-3"
            >
              <div class="flex items-start justify-between gap-3 flex-wrap">
                <div class="min-w-0">
                  <div class="flex items-center gap-2 flex-wrap">
                    <Tag
                      :value="eventLabel(ev.event_type)"
                      :severity="eventSeverity(ev.event_type)"
                      rounded
                    />
                    <span class="text-sm text-color-secondary">
                      por <b>{{ displayUser(ev.created_by) }}</b>
                    </span>
                  </div>

                  <!-- De → Para (quando existir) -->
                  <div v-if="ev.old_plan_id || ev.new_plan_id" class="mt-2 text-sm">
                    <span class="text-color-secondary">Plano:</span>
                    <span class="font-medium ml-2">{{ planKeyOrName(ev.old_plan_id) }}</span>
                    <i class="pi pi-arrow-right text-color-secondary mx-2" />
                    <span class="font-medium">{{ planKeyOrName(ev.new_plan_id) }}</span>
                  </div>

                  <div v-if="ev.reason" class="mt-2 text-sm opacity-80">
                    {{ ev.reason }}
                  </div>
                </div>

                <div class="text-sm text-color-secondary">
                  {{ fmtDate(ev.created_at) }}
                </div>
              </div>

              <div class="mt-2 text-xs text-color-secondary" v-if="ev.metadata">
                <pre class="m-0 whitespace-pre-wrap break-words">{{ prettyMeta(ev.metadata) }}</pre>
              </div>
            </div>
          </div>

          <div class="mt-4 text-xs text-color-secondary">
            Mostrando até 50 eventos (mais recentes).
          </div>
        </template>
      </Card>
    </div>
  </div>
</template>

<style scoped>
/* (intencionalmente vazio) */
</style>