<!-- front-end/app/pages/index.vue -->
<script setup lang="ts">
import { PIPELINE_ETAPAS } from '~/types'

const { apiFetch } = useApi()

interface ApiEdital {
  ID: string; Numero: string; Orgao: string; Modalidade: string
  Objeto: string; Plataforma: string; ValorEstimado: number
  DataPublicacao: string; DataAbertura: string; Status: string
}
interface ApiDocument {
  ID: string; Tipo: string; Nome: string
  DataVencimento: string | null; Observacoes: string
}
interface ApiContract {
  ID: string; Numero: string; Orgao: string; Objeto: string
  Valor: number; DataInicio: string; DataFim: string; Status: string
}

const { data: editais } = await useAsyncData('dash-editais', () =>
  apiFetch<ApiEdital[]>('/editais'), { server: false, default: () => [] }
)
const { data: documentos } = await useAsyncData('dash-docs', () =>
  apiFetch<ApiDocument[]>('/documents'), { server: false, default: () => [] }
)
const { data: contratos } = await useAsyncData('dash-contratos', () =>
  apiFetch<ApiContract[]>('/contracts'), { server: false, default: () => [] }
)

// ---------- helpers ----------
const hoje = new Date()
const dataFormatada = hoje.toLocaleDateString('pt-BR', { day: 'numeric', month: 'long', year: 'numeric' })

const MODALIDADE: Record<string, string> = {
  pregao_eletronico: 'Pregão Eletrônico', pregao_presencial: 'Pregão Presencial',
  concorrencia: 'Concorrência', dispensa: 'Dispensa', inexigibilidade: 'Inexigibilidade',
}
const STATUS_CFG: Record<string, { label: string; color: string; bg: string }> = {
  em_analise:          { label: 'Mapeamento',           color: '#0284c7', bg: '#eff6ff' },
  elaborando_proposta: { label: 'Termo de Referência',  color: '#7c3aed', bg: '#faf5ff' },
  edital_publicado:    { label: 'Edital Publicado',     color: '#ea580c', bg: '#fff7ed' },
  fase_lances:         { label: 'Fase de Lances',       color: '#3b82f6', bg: '#eff6ff' },
  habilitacao:         { label: 'Habilitação',          color: '#d97706', bg: '#fef3c7' },
  recurso:             { label: 'Recursos',             color: '#d97706', bg: '#fffbeb' },
  adjudicado:          { label: 'Adjudicado',           color: '#059669', bg: '#ecfdf5' },
  contrato:            { label: 'Contrato',             color: '#16a34a', bg: '#f0fdf4' },
  vencida:             { label: 'Vencida',              color: '#16a34a', bg: '#f0fdf4' },
  perdida:             { label: 'Perdida',              color: '#dc2626', bg: '#fef2f2' },
  deserta:             { label: 'Deserta/Fracassada',   color: '#64748b', bg: '#f8fafc' },
}
const TIPO_DOC: Record<string, string> = {
  cnpj: 'CNPJ', contrato_social: 'Contrato Social', balanco: 'Balanço',
  certidao: 'Certidão', atestado: 'Atestado Técnico', procuracao: 'Procuração', outro: 'Outro',
}

function formatDate(iso: string): string {
  if (!iso) return '—'
  const [y, m, d] = iso.split('T')[0].split('-')
  return `${d}/${m}/${y}`
}
function formatBRL(v: number): string {
  return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL', maximumFractionDigits: 0 }).format(v)
}
function diffDays(iso: string): number {
  const hojeMs = Date.UTC(hoje.getFullYear(), hoje.getMonth(), hoje.getDate())
  const [y, m, d] = iso.split('T')[0].split('-').map(Number)
  return Math.ceil((Date.UTC(y, m - 1, d) - hojeMs) / (1000 * 60 * 60 * 24))
}
function diasLabel(diff: number): string {
  if (diff < 0) return `${Math.abs(diff)}d atrás`
  if (diff === 0) return 'Hoje'
  if (diff === 1) return 'Amanhã'
  return `em ${diff}d`
}

// ---------- stats ----------
const totalEditais = computed(() => editais.value.length)
const vencidas = computed(() => editais.value.filter(e => e.Status === 'vencida').length)
const taxaVitoria = computed(() => {
  const finalizados = editais.value.filter(e => ['vencida', 'perdida', 'deserta'].includes(e.Status))
  if (finalizados.length === 0) return 0
  return Math.round((vencidas.value / finalizados.length) * 100)
})
const valorContratosAtivos = computed(() =>
  contratos.value.filter(c => c.Status === 'ativo').reduce((sum, c) => sum + (c.Valor ?? 0), 0)
)

// Alertas = docs vencendo/vencidos + prazos editais próximos
const alertasAtivos = computed(() => {
  let count = 0
  for (const d of documentos.value) {
    if (!d.DataVencimento) continue
    const diff = diffDays(d.DataVencimento)
    if (diff <= 30) count++
  }
  const statusAtivos = new Set(['em_analise', 'elaborando_proposta', 'edital_publicado', 'fase_lances', 'habilitacao', 'recurso'])
  for (const e of editais.value) {
    if (!statusAtivos.has(e.Status)) continue
    const diff = diffDays(e.DataAbertura)
    if (diff >= 0 && diff <= 7) count++
  }
  return count
})

// ---------- pipeline ----------
const statusParaEtapa: Record<string, number> = {
  em_analise: 1, elaborando_proposta: 2, edital_publicado: 3,
  fase_lances: 4, habilitacao: 5, recurso: 6,
  adjudicado: 7, contrato: 8, vencida: 8, perdida: 8, deserta: 8,
}

const contagemPorEtapa = computed(() => {
  const counts: Record<number, number> = {}
  for (const e of editais.value) {
    const etapa = statusParaEtapa[e.Status] ?? 1
    counts[etapa] = (counts[etapa] ?? 0) + 1
  }
  return counts
})

// ---------- prazos urgentes (próx 30 dias) ----------
interface PrazoItem {
  id: string; titulo: string; sub: string; dataIso: string
  diff: number; tipo: 'edital' | 'documento' | 'contrato'; link: string
}

const prazosUrgentes = computed<PrazoItem[]>(() => {
  const items: PrazoItem[] = []
  const statusAtivos = new Set(['em_analise', 'elaborando_proposta', 'edital_publicado', 'fase_lances', 'habilitacao', 'recurso'])
  for (const e of editais.value) {
    if (!statusAtivos.has(e.Status)) continue
    const d = diffDays(e.DataAbertura)
    if (d > 30) continue
    items.push({
      id: `e-${e.ID}`, titulo: `Abertura — ${e.Numero}`,
      sub: `${e.Orgao}`, dataIso: e.DataAbertura, diff: d,
      tipo: 'edital', link: `/oportunidades/${e.ID}`,
    })
  }
  for (const doc of documentos.value) {
    if (!doc.DataVencimento) continue
    const d = diffDays(doc.DataVencimento)
    if (d > 30) continue
    items.push({
      id: `d-${doc.ID}`, titulo: `Vencimento — ${doc.Nome || TIPO_DOC[doc.Tipo] || doc.Tipo}`,
      sub: TIPO_DOC[doc.Tipo] || doc.Tipo, dataIso: doc.DataVencimento, diff: d,
      tipo: 'documento', link: '/gestao/documentos',
    })
  }
  for (const c of contratos.value) {
    if (!c.DataFim || c.Status === 'encerrado') continue
    const d = diffDays(c.DataFim)
    if (d > 30) continue
    items.push({
      id: `c-${c.ID}`, titulo: `Fim vigência — ${c.Numero}`,
      sub: c.Orgao, dataIso: c.DataFim, diff: d,
      tipo: 'contrato', link: '/gestao/contratos',
    })
  }
  items.sort((a, b) => a.diff - b.diff)
  return items.slice(0, 6)
})

function urgenciaCor(diff: number): string {
  if (diff < 0) return '#dc2626'
  if (diff === 0) return '#dc2626'
  if (diff <= 7) return '#ea580c'
  return '#d97706'
}

// ---------- docs com alerta ----------
const docsAlerta = computed(() => {
  return documentos.value
    .filter(d => {
      if (!d.DataVencimento) return false
      return diffDays(d.DataVencimento) <= 30
    })
    .sort((a, b) => diffDays(a.DataVencimento!) - diffDays(b.DataVencimento!))
    .slice(0, 5)
})

function docStatus(d: ApiDocument) {
  if (!d.DataVencimento) return { label: 'OK', color: '#64748b', bg: '#f8fafc' }
  const diff = diffDays(d.DataVencimento)
  if (diff < 0) return { label: 'Vencida', color: '#dc2626', bg: '#fef2f2' }
  if (diff <= 30) return { label: 'Vencendo', color: '#d97706', bg: '#fffbeb' }
  return { label: 'Válida', color: '#16a34a', bg: '#f0fdf4' }
}

// ---------- editais recentes ----------
const editaisRecentes = computed(() =>
  [...editais.value]
    .sort((a, b) => new Date(b.DataAbertura).getTime() - new Date(a.DataAbertura).getTime())
    .slice(0, 5)
)
</script>

<template>
  <div class="page">
    <AppTopbar title="Dashboard" :breadcrumb="`Visão geral · ${dataFormatada}`">
      <template #actions>
        <NuxtLink to="/oportunidades" class="btn-outline-sm">Ver Oportunidades</NuxtLink>
      </template>
    </AppTopbar>

    <div class="content">
      <!-- Stats -->
      <div class="stats-grid">
        <div class="stat-card">
          <p class="stat-label">Total de Editais</p>
          <p class="stat-value">{{ totalEditais }}</p>
          <p class="stat-sub">Cadastrados</p>
        </div>
        <div class="stat-card">
          <p class="stat-label">Taxa de Vitória</p>
          <p class="stat-value" style="color: #10b981">{{ taxaVitoria }}%</p>
          <p class="stat-sub">Processos finalizados</p>
        </div>
        <div class="stat-card">
          <p class="stat-label">Contratos Ativos</p>
          <p class="stat-value" style="color: #667eea">{{ formatBRL(valorContratosAtivos) }}</p>
          <p class="stat-sub">{{ contratos.filter(c => c.Status === 'ativo').length }} contratos</p>
        </div>
        <div class="stat-card">
          <p class="stat-label">Alertas Ativos</p>
          <p class="stat-value" :style="{ color: alertasAtivos > 0 ? '#f59e0b' : '#94a3b8' }">{{ alertasAtivos }}</p>
          <p class="stat-sub">Requerem atenção</p>
        </div>
      </div>

      <!-- Pipeline -->
      <div class="card mb-4">
        <div class="card-header">
          <h3>Pipeline de Oportunidades</h3>
          <NuxtLink to="/pipeline" class="card-link">Ver kanban →</NuxtLink>
        </div>
        <div class="pipeline-wrap">
          <PipelineBar :contagem-por-etapa="contagemPorEtapa" />
        </div>
      </div>

      <!-- Grid 2 colunas -->
      <div class="grid-2 mb-4">
        <!-- Alertas de Prazo -->
        <div class="card">
          <div class="card-header">
            <h3>Alertas de Prazo</h3>
            <NuxtLink to="/gestao/prazos" class="card-link">Ver todos →</NuxtLink>
          </div>
          <div v-if="prazosUrgentes.length === 0" class="empty-section">
            <p>Nenhum prazo urgente nos próximos 30 dias</p>
          </div>
          <NuxtLink
            v-for="p in prazosUrgentes" :key="p.id"
            :to="p.link"
            class="alert-item"
          >
            <div class="alert-dot" :style="{ background: urgenciaCor(p.diff) }" />
            <div class="alert-text">
              <p class="at">{{ p.titulo }}</p>
              <p class="as">{{ p.sub }}</p>
            </div>
            <div class="alert-right">
              <span class="alert-date" :style="{ color: urgenciaCor(p.diff) }">{{ diasLabel(p.diff) }}</span>
              <span class="alert-date-full">{{ formatDate(p.dataIso) }}</span>
            </div>
          </NuxtLink>
        </div>

        <!-- Documentos -->
        <div class="card">
          <div class="card-header">
            <h3>Documentos com Alerta</h3>
            <NuxtLink to="/gestao/documentos" class="card-link">Gerenciar →</NuxtLink>
          </div>
          <div v-if="docsAlerta.length === 0" class="empty-section">
            <p>Todos os documentos estão em dia</p>
          </div>
          <NuxtLink
            v-for="d in docsAlerta" :key="d.ID"
            to="/gestao/documentos"
            class="doc-item"
          >
            <div>
              <p class="doc-nome">{{ d.Nome || TIPO_DOC[d.Tipo] || d.Tipo }}</p>
              <p class="doc-sub">{{ TIPO_DOC[d.Tipo] || d.Tipo }} · {{ formatDate(d.DataVencimento!) }}</p>
            </div>
            <span
              class="doc-badge"
              :style="{ color: docStatus(d).color, background: docStatus(d).bg }"
            >{{ docStatus(d).label }}</span>
          </NuxtLink>
        </div>
      </div>

      <!-- Tabela Editais Recentes -->
      <div class="card">
        <div class="card-header">
          <h3>Editais Recentes</h3>
          <NuxtLink to="/oportunidades" class="card-link">Ver todos →</NuxtLink>
        </div>
        <div v-if="editaisRecentes.length === 0" class="empty-section">
          <p>Nenhum edital cadastrado ainda</p>
        </div>
        <table v-else class="tbl">
          <thead>
            <tr>
              <th>Nº Edital</th>
              <th>Órgão</th>
              <th>Objeto</th>
              <th>Modalidade</th>
              <th>Valor Est.</th>
              <th>Abertura</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="e in editaisRecentes" :key="e.ID"
              class="row-click"
              @click="navigateTo(`/oportunidades/${e.ID}`)"
            >
              <td class="td-num">{{ e.Numero }}</td>
              <td>{{ e.Orgao }}</td>
              <td class="td-obj">{{ e.Objeto }}</td>
              <td>{{ MODALIDADE[e.Modalidade] ?? e.Modalidade }}</td>
              <td class="td-val">{{ formatBRL(e.ValorEstimado) }}</td>
              <td>{{ formatDate(e.DataAbertura) }}</td>
              <td>
                <span
                  v-if="STATUS_CFG[e.Status]"
                  class="badge"
                  :style="{ background: STATUS_CFG[e.Status].bg, color: STATUS_CFG[e.Status].color }"
                >{{ STATUS_CFG[e.Status].label }}</span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<style scoped>
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300..700&family=JetBrains+Mono:wght@400;600&display=swap');

.page { display: flex; flex-direction: column; height: 100vh; font-family: 'DM Sans', system-ui, sans-serif; }
.content { padding: 24px 28px 40px; flex: 1; overflow-y: auto; }

.btn-outline-sm {
  padding: 6px 14px; border-radius: 7px; border: 1px solid #e2e8f0;
  background: white; font-size: 12px; font-weight: 600; color: #475569;
  text-decoration: none; transition: all .15s;
}
.btn-outline-sm:hover { background: #f8fafc; border-color: #cbd5e1; }

/* ── Stats ── */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 18px; }
.stat-card {
  background: white; border-radius: 12px; padding: 18px 20px;
  border: 1px solid #e2e8f0; box-shadow: 0 1px 3px rgba(0,0,0,.04);
}
.stat-label { font-size: 11px; color: #94a3b8; text-transform: uppercase; letter-spacing: .5px; font-weight: 700; margin-bottom: 8px; }
.stat-value { font-size: 28px; font-weight: 800; color: #0f172a; line-height: 1; font-family: 'JetBrains Mono', monospace; }
.stat-sub { font-size: 11px; color: #64748b; margin-top: 6px; }

/* ── Cards ── */
.card { background: white; border-radius: 12px; border: 1px solid #e2e8f0; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.04); }
.mb-4 { margin-bottom: 18px; }
.card-header {
  padding: 16px 20px 12px; border-bottom: 1px solid #f1f5f9;
  display: flex; align-items: center; justify-content: space-between;
}
.card-header h3 { font-size: 14px; font-weight: 700; color: #0f172a; margin: 0; }
.card-link { font-size: 12px; color: #667eea; text-decoration: none; font-weight: 600; }
.card-link:hover { text-decoration: underline; }
.pipeline-wrap { padding: 0 20px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.empty-section { padding: 28px 20px; text-align: center; }
.empty-section p { font-size: 13px; color: #94a3b8; margin: 0; }

/* ── Alertas ── */
.alert-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 20px; border-bottom: 1px solid #f5f7fa;
  text-decoration: none; transition: background .12s;
}
.alert-item:last-child { border-bottom: none; }
.alert-item:hover { background: #fafbfd; }
.alert-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.alert-text { flex: 1; min-width: 0; }
.at { font-size: 13px; font-weight: 600; color: #0f172a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.as { font-size: 11.5px; color: #94a3b8; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.alert-right { text-align: right; flex-shrink: 0; }
.alert-date { font-size: 12px; font-weight: 700; display: block; }
.alert-date-full { font-size: 10.5px; color: #94a3b8; display: block; margin-top: 1px; }

/* ── Docs ── */
.doc-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 20px; border-bottom: 1px solid #f5f7fa;
  text-decoration: none; transition: background .12s;
}
.doc-item:last-child { border-bottom: none; }
.doc-item:hover { background: #fafbfd; }
.doc-nome { font-size: 13px; font-weight: 600; color: #0f172a; }
.doc-sub { font-size: 11.5px; color: #94a3b8; margin-top: 1px; }
.doc-badge { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 20px; flex-shrink: 0; }

/* ── Table ── */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl thead tr { border-bottom: 1px solid #e2e8f0; background: #f8fafc; }
.tbl th {
  padding: 10px 16px; text-align: left; font-weight: 700; color: #64748b;
  font-size: 11px; text-transform: uppercase; letter-spacing: .4px; white-space: nowrap;
}
.tbl td { padding: 12px 16px; color: #1e293b; border-bottom: 1px solid #f5f7fa; vertical-align: middle; }
.tbl tbody tr:last-child td { border-bottom: none; }
.row-click { cursor: pointer; transition: background .12s; }
.row-click:hover td { background: #fafbfd; }
.td-num { font-weight: 700; white-space: nowrap; }
.td-obj { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-val { font-family: 'JetBrains Mono', monospace; font-size: 12px; white-space: nowrap; }
.badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; }

/* ── Responsive ── */
@media (max-width: 900px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .grid-2 { grid-template-columns: 1fr; }
}
</style>
