<!-- front-end/app/pages/gestao/documentos.vue -->
<script setup lang="ts">
const { apiFetch } = useApi()
const { public: { apiBase } } = useRuntimeConfig()
const token = useCookie<string | null>('auth_token')

interface ApiDocument {
  ID: string
  Tipo: string
  Nome: string
  DataVencimento: string | null
  Observacoes: string
}

interface ApiFile {
  ID: string
  Nome: string
  Size: number
  CreatedAt: string
}

const { data: documentos, refresh } = await useAsyncData('documentos', () =>
  apiFetch<ApiDocument[]>('/documents')
)

// ---------- tipos ----------
const TIPOS = [
  { value: 'cnpj',            label: 'CNPJ' },
  { value: 'contrato_social', label: 'Contrato Social' },
  { value: 'balanco',         label: 'Balanço' },
  { value: 'certidao',        label: 'Certidão' },
  { value: 'atestado',        label: 'Atestado de Capacidade Técnica' },
  { value: 'procuracao',      label: 'Procuração' },
  { value: 'outro',           label: 'Outro' },
]

function tipoLabel(tipo: string): string {
  return TIPOS.find(t => t.value === tipo)?.label ?? tipo
}

// ---------- status ----------
function calcStatus(dataVenc: string | null): 'sem_vencimento' | 'vencida' | 'vencendo' | 'valida' {
  if (!dataVenc) return 'sem_vencimento'
  const hoje = new Date()
  const hojeMs = Date.UTC(hoje.getFullYear(), hoje.getMonth(), hoje.getDate())
  const dateStr = dataVenc.split('T')[0] // "YYYY-MM-DD"
  const [y, m, d] = dateStr.split('-').map(Number)
  const vencMs = Date.UTC(y, m - 1, d)
  const diff = (vencMs - hojeMs) / (1000 * 60 * 60 * 24)
  if (diff < 0)  return 'vencida'
  if (diff <= 30) return 'vencendo'
  return 'valida'
}

const STATUS_CFG = {
  valida:         { label: 'Válida',   color: '#16a34a', bg: '#f0fdf4' },
  vencendo:       { label: 'Vencendo', color: '#d97706', bg: '#fffbeb' },
  vencida:        { label: 'Vencida',  color: '#dc2626', bg: '#fef2f2' },
  sem_vencimento: { label: 'OK',       color: '#64748b', bg: '#f8fafc' },
}

function formatDate(iso: string | null): string {
  if (!iso) return 'Sem vencimento'
  const [y, m, d] = iso.split('T')[0].split('-')
  return `${d}/${m}/${y}`
}

function formatFileSize(bytes: number) {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}

// ---------- menu ⋯ ----------
const menuAberto = ref<string | null>(null)
const menuPos = ref({ top: 0, left: 0 })

function abrirMenu(id: string, event: MouseEvent) {
  const btn = (event.currentTarget as HTMLElement)
  const rect = btn.getBoundingClientRect()
  menuPos.value = { top: rect.bottom + 4, left: rect.left - 100 }
  menuAberto.value = menuAberto.value === id ? null : id
}

function fecharMenu() { menuAberto.value = null }

// ---------- modal visualizar ----------
const showVisualizar = ref(false)
const viewDoc = ref<ApiDocument | null>(null)
const viewFiles = ref<ApiFile[]>([])
const viewFilesLoading = ref(false)
const uploadLoading = ref(false)

async function abrirVisualizar(doc: ApiDocument) {
  fecharMenu()
  viewDoc.value = doc
  showVisualizar.value = true
  viewFilesLoading.value = true
  try {
    viewFiles.value = await apiFetch<ApiFile[]>(`/documents/${doc.ID}/files`)
  } catch { viewFiles.value = [] }
  viewFilesLoading.value = false
}

async function uploadArquivos(event: Event) {
  const input = event.target as HTMLInputElement
  if (!input.files?.length || !viewDoc.value) return
  uploadLoading.value = true
  const formData = new FormData()
  for (const file of Array.from(input.files)) formData.append('file', file)
  try {
    await $fetch(`${apiBase}/documents/${viewDoc.value.ID}/files`, {
      method: 'POST',
      headers: { Authorization: `Bearer ${token.value}` },
      body: formData,
    })
    viewFiles.value = await apiFetch<ApiFile[]>(`/documents/${viewDoc.value.ID}/files`)
  } catch {}
  uploadLoading.value = false
  input.value = ''
}

async function excluirArquivo(fileId: string) {
  if (!viewDoc.value) return
  try {
    await apiFetch(`/documents/${viewDoc.value.ID}/files/${fileId}`, { method: 'DELETE' })
    viewFiles.value = viewFiles.value.filter(f => f.ID !== fileId)
  } catch {}
}

async function downloadArquivo(docId: string, fileId: string, nome: string) {
  try {
    const blob = await $fetch<Blob>(`${apiBase}/documents/${docId}/files/${fileId}/download`, {
      headers: { Authorization: `Bearer ${token.value}` },
      responseType: 'blob',
    })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = nome
    a.click()
    URL.revokeObjectURL(url)
  } catch {}
}

// ---------- modal criar ----------
const showCriar = ref(false)
const criando = ref(false)
const erroCreate = ref('')

const createForm = reactive({
  tipo: '',
  nome: '',
  data_vencimento: '',
  observacoes: '',
})

function abrirCriar() {
  createForm.tipo = ''
  createForm.nome = ''
  createForm.data_vencimento = ''
  createForm.observacoes = ''
  erroCreate.value = ''
  showCriar.value = true
}

async function criarDocumento() {
  criando.value = true
  erroCreate.value = ''
  try {
    await apiFetch('/documents', {
      method: 'POST',
      body: {
        tipo: createForm.tipo,
        nome: createForm.nome,
        data_vencimento: createForm.data_vencimento || '',
        observacoes: createForm.observacoes,
      },
    })
    showCriar.value = false
    await refresh()
  } catch {
    erroCreate.value = 'Erro ao criar documento.'
  } finally {
    criando.value = false
  }
}

// ---------- modal editar ----------
const showEditar = ref(false)
const editando = ref(false)
const erroEdit = ref('')
const editId = ref('')

const editForm = reactive({
  tipo: '',
  nome: '',
  data_vencimento: '',
  observacoes: '',
})

function abrirEditar(doc: ApiDocument) {
  fecharMenu()
  editId.value = doc.ID
  editForm.tipo = doc.Tipo
  editForm.nome = doc.Nome
  editForm.data_vencimento = doc.DataVencimento ? doc.DataVencimento.split('T')[0] : ''
  editForm.observacoes = doc.Observacoes
  erroEdit.value = ''
  showEditar.value = true
}

async function salvarDocumento() {
  editando.value = true
  erroEdit.value = ''
  try {
    await apiFetch(`/documents/${editId.value}`, {
      method: 'PUT',
      body: {
        tipo: editForm.tipo,
        nome: editForm.nome,
        data_vencimento: editForm.data_vencimento || '',
        observacoes: editForm.observacoes,
      },
    })
    showEditar.value = false
    await refresh()
  } catch {
    erroEdit.value = 'Erro ao salvar documento.'
  } finally {
    editando.value = false
  }
}

// ---------- confirmação exclusão ----------
const showExcluir = ref(false)
const excluindo = ref(false)
const docParaExcluir = ref<ApiDocument | null>(null)

function abrirExcluir(doc: ApiDocument) {
  fecharMenu()
  docParaExcluir.value = doc
  showExcluir.value = true
}

async function confirmarExclusao() {
  if (!docParaExcluir.value) return
  excluindo.value = true
  try {
    await apiFetch(`/documents/${docParaExcluir.value.ID}`, { method: 'DELETE' })
    showExcluir.value = false
    await refresh()
  } finally {
    excluindo.value = false
  }
}
</script>

<template>
  <div class="page" @click="fecharMenu">
    <AppTopbar title="Documentos da Empresa" breadcrumb="Gestão · Documentos">
      <template #actions>
        <button class="btn-primary" @click.stop="abrirCriar">+ Adicionar Documento</button>
      </template>
    </AppTopbar>

    <div class="content">
      <div class="card">
        <div v-if="!documentos || documentos.length === 0" class="empty">
          Nenhum documento cadastrado.
        </div>
        <div v-for="doc in documentos" :key="doc.ID" class="doc-row">
          <div class="doc-info">
            <p class="doc-nome">{{ doc.Nome || tipoLabel(doc.Tipo) }}</p>
            <p class="doc-meta">{{ tipoLabel(doc.Tipo) }} · {{ formatDate(doc.DataVencimento) }}</p>
          </div>
          <div class="doc-right">
            <span
              class="doc-status"
              :style="{ color: STATUS_CFG[calcStatus(doc.DataVencimento)].color, background: STATUS_CFG[calcStatus(doc.DataVencimento)].bg }"
            >
              {{ STATUS_CFG[calcStatus(doc.DataVencimento)].label }}
            </span>
            <button class="btn-menu" @click.stop="abrirMenu(doc.ID, $event)">⋯</button>
          </div>
        </div>
      </div>
    </div>

    <!-- Menu flutuante -->
    <Teleport to="body">
      <div
        v-if="menuAberto"
        class="dropdown-fixed"
        :style="{ top: menuPos.top + 'px', left: menuPos.left + 'px' }"
        @click.stop
      >
        <button @click="abrirVisualizar(documentos!.find(d => d.ID === menuAberto)!); menuAberto = null">Visualizar</button>
        <button @click="abrirEditar(documentos!.find(d => d.ID === menuAberto)!)">Editar</button>
        <button class="drop-danger" @click="abrirExcluir(documentos!.find(d => d.ID === menuAberto)!)">Excluir</button>
      </div>
    </Teleport>

    <!-- Modal Visualizar -->
    <Teleport to="body">
      <div v-if="showVisualizar" class="modal-overlay" @click.self="showVisualizar = false">
        <div class="modal modal-view">
          <div class="modal-header">
            <div>
              <h2>{{ viewDoc?.Nome || tipoLabel(viewDoc?.Tipo ?? '') }}</h2>
              <span
                class="doc-status"
                :style="{ color: STATUS_CFG[calcStatus(viewDoc?.DataVencimento ?? null)].color, background: STATUS_CFG[calcStatus(viewDoc?.DataVencimento ?? null)].bg }"
              >
                {{ STATUS_CFG[calcStatus(viewDoc?.DataVencimento ?? null)].label }}
              </span>
            </div>
            <button class="close-btn" @click="showVisualizar = false">✕</button>
          </div>
          <div class="view-grid">
            <div class="view-field">
              <label>Tipo</label>
              <span>{{ tipoLabel(viewDoc?.Tipo ?? '') }}</span>
            </div>
            <div class="view-field">
              <label>Vencimento</label>
              <span>{{ formatDate(viewDoc?.DataVencimento ?? null) }}</span>
            </div>
            <div class="view-field view-full">
              <label>Observações</label>
              <span>{{ viewDoc?.Observacoes || '—' }}</span>
            </div>
          </div>

          <div class="files-section">
            <div class="files-header">
              <h3>Arquivos</h3>
              <label class="upload-btn" :class="{ loading: uploadLoading }">
                <input type="file" multiple @change="uploadArquivos" style="display:none" :disabled="uploadLoading" />
                {{ uploadLoading ? 'Enviando...' : '+ Anexar' }}
              </label>
            </div>
            <div v-if="viewFilesLoading" class="files-empty">Carregando arquivos...</div>
            <div v-else-if="viewFiles.length === 0" class="files-empty">Nenhum arquivo anexado.</div>
            <div v-else class="files-list">
              <div v-for="f in viewFiles" :key="f.ID" class="file-item">
                <span class="file-icon">📄</span>
                <span class="file-name">{{ f.Nome }}</span>
                <span class="file-size">{{ formatFileSize(f.Size) }}</span>
                <button class="file-act" title="Download" @click="downloadArquivo(viewDoc!.ID, f.ID, f.Nome)">⬇</button>
                <button class="file-act file-del" title="Remover" @click="excluirArquivo(f.ID)">✕</button>
              </div>
            </div>
          </div>

          <div class="modal-footer">
            <button class="btn-cancel" @click="showVisualizar = false">Fechar</button>
            <button class="btn-save" @click="showVisualizar = false; abrirEditar(viewDoc!)">Editar</button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- Modal Criar -->
    <Teleport to="body">
      <div v-if="showCriar" class="modal-overlay" @click.self="showCriar = false">
        <div class="modal">
          <div class="modal-header">
            <h2>Novo Documento</h2>
            <button @click="showCriar = false">✕</button>
          </div>
          <div class="modal-body">
            <div class="field">
              <label>Tipo *</label>
              <select v-model="createForm.tipo" class="field-select">
                <option value="" disabled>Selecione o tipo</option>
                <option v-for="t in TIPOS" :key="t.value" :value="t.value">{{ t.label }}</option>
              </select>
            </div>
            <div class="field">
              <label>Nome / Identificação</label>
              <UInput v-model="createForm.nome" placeholder="Ex: CND Federal, Certidão Estadual SP" class="w-full" />
            </div>
            <div class="field">
              <label>Data de Vencimento</label>
              <UInput v-model="createForm.data_vencimento" type="date" class="w-full" />
            </div>
            <div class="field">
              <label>Observações</label>
              <UTextarea v-model="createForm.observacoes" placeholder="Informações adicionais..." class="w-full" />
            </div>
            <p v-if="erroCreate" class="erro">{{ erroCreate }}</p>
          </div>
          <div class="modal-footer">
            <button class="btn-cancel" @click="showCriar = false">Cancelar</button>
            <button class="btn-save" :disabled="criando || !createForm.tipo" @click="criarDocumento">
              {{ criando ? 'Criando...' : 'Criar' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- Modal Editar -->
    <Teleport to="body">
      <div v-if="showEditar" class="modal-overlay" @click.self="showEditar = false">
        <div class="modal">
          <div class="modal-header">
            <h2>Editar Documento</h2>
            <button @click="showEditar = false">✕</button>
          </div>
          <div class="modal-body">
            <div class="field">
              <label>Tipo *</label>
              <select v-model="editForm.tipo" class="field-select">
                <option value="" disabled>Selecione o tipo</option>
                <option v-for="t in TIPOS" :key="t.value" :value="t.value">{{ t.label }}</option>
              </select>
            </div>
            <div class="field">
              <label>Nome / Identificação</label>
              <UInput v-model="editForm.nome" class="w-full" />
            </div>
            <div class="field">
              <label>Data de Vencimento</label>
              <UInput v-model="editForm.data_vencimento" type="date" class="w-full" />
            </div>
            <div class="field">
              <label>Observações</label>
              <UTextarea v-model="editForm.observacoes" class="w-full" />
            </div>
            <p v-if="erroEdit" class="erro">{{ erroEdit }}</p>
          </div>
          <div class="modal-footer">
            <button class="btn-cancel" @click="showEditar = false">Cancelar</button>
            <button class="btn-save" :disabled="editando || !editForm.tipo" @click="salvarDocumento">
              {{ editando ? 'Salvando...' : 'Salvar' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- Modal Excluir -->
    <Teleport to="body">
      <div v-if="showExcluir" class="modal-overlay" @click.self="showExcluir = false">
        <div class="modal modal-sm">
          <div class="modal-header">
            <h2>Excluir Documento</h2>
            <button @click="showExcluir = false">✕</button>
          </div>
          <div class="modal-body">
            <p>Tem certeza que deseja excluir <strong>{{ docParaExcluir?.Nome || tipoLabel(docParaExcluir?.Tipo ?? '') }}</strong>?</p>
            <p style="color:#94a3b8;font-size:12px;margin-top:6px">Esta ação não pode ser desfeita.</p>
          </div>
          <div class="modal-footer">
            <button class="btn-cancel" @click="showExcluir = false">Cancelar</button>
            <button class="btn-danger" :disabled="excluindo" @click="confirmarExclusao">
              {{ excluindo ? 'Excluindo...' : 'Excluir' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>
  </div>
</template>

<style scoped>
.page { display: flex; flex-direction: column; height: 100vh; }
.content { padding: 20px 22px; flex: 1; overflow-y: auto; }
.card { background: white; border-radius: 11px; border: 1px solid #e2e8f0; overflow: hidden; }
.empty { padding: 32px; text-align: center; color: #94a3b8; font-size: 13px; }

.doc-row { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid #f8fafc; }
.doc-row:last-child { border-bottom: none; }
.doc-info { flex: 1; }
.doc-nome { font-size: 13px; font-weight: 600; color: #0f172a; }
.doc-meta { font-size: 11px; color: #94a3b8; margin-top: 2px; }
.doc-right { display: flex; align-items: center; gap: 10px; }
.doc-status { font-size: 11px; font-weight: 600; padding: 3px 10px; border-radius: 20px; }

.btn-menu { background: none; border: none; font-size: 18px; cursor: pointer; color: #94a3b8; padding: 2px 6px; border-radius: 4px; }
.btn-menu:hover { background: #f1f5f9; color: #334155; }
.btn-primary { background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; border-radius: 8px; padding: 7px 14px; font-size: 13px; font-weight: 600; cursor: pointer; }

.modal-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 18px 20px 12px; border-bottom: 1px solid #f1f5f9; }
.modal-header h2 { font-size: 16px; font-weight: 700; color: #0f172a; margin: 0 0 6px; }
.modal-header button { background: none; border: none; font-size: 18px; cursor: pointer; color: #94a3b8; }
.close-btn { background: none; border: none; font-size: 16px; color: #94a3b8; cursor: pointer; padding: 4px 8px; border-radius: 6px; }
.close-btn:hover { background: #f1f5f9; color: #475569; }
.modal-body { padding: 16px 20px; display: flex; flex-direction: column; gap: 14px; }
.modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 12px 20px 18px; border-top: 1px solid #f1f5f9; }

.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 12px; font-weight: 600; color: #374151; }
.field-select { width: 100%; border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px 11px; font-size: 13px; color: #0f172a; background: white; outline: none; }
.field-select:focus { border-color: #667eea; }

.btn-cancel { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 7px 16px; font-size: 13px; cursor: pointer; }
.btn-save { background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; border-radius: 8px; padding: 7px 16px; font-size: 13px; font-weight: 600; cursor: pointer; }
.btn-save:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-danger { background: #dc2626; color: white; border: none; border-radius: 8px; padding: 7px 16px; font-size: 13px; font-weight: 600; cursor: pointer; }
.btn-danger:disabled { opacity: 0.6; cursor: not-allowed; }
.erro { color: #dc2626; font-size: 12px; }

/* Modal visualizar */
.modal-view { max-width: 620px !important; }
.view-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 16px 20px 4px; }
.view-full { grid-column: 1 / -1; }
.view-field { display: flex; flex-direction: column; gap: 3px; }
.view-field label { font-size: 11px; font-weight: 700; color: #94a3b8; text-transform: uppercase; letter-spacing: 0.5px; }
.view-field span { font-size: 13px; color: #1e293b; }

/* Arquivos */
.files-section { border-top: 1px solid #f1f5f9; padding: 16px 20px 4px; margin-top: 8px; }
.files-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.files-header h3 { font-size: 11px; font-weight: 700; color: #94a3b8; margin: 0; text-transform: uppercase; letter-spacing: 0.5px; }
.upload-btn { font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: 8px; border: 1px dashed #667eea; color: #667eea; cursor: pointer; transition: all 0.15s; }
.upload-btn:hover { background: #f0f3ff; }
.upload-btn.loading { opacity: 0.6; cursor: not-allowed; }
.files-empty { font-size: 13px; color: #94a3b8; text-align: center; padding: 16px 0; }
.files-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.file-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #f8fafc; border-radius: 8px; border: 1px solid #e2e8f0; }
.file-icon { font-size: 16px; flex-shrink: 0; }
.file-name { flex: 1; font-size: 13px; color: #1e293b; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-size { font-size: 11px; color: #94a3b8; white-space: nowrap; flex-shrink: 0; }
.file-act { font-size: 13px; padding: 3px 7px; background: none; border: none; cursor: pointer; color: #667eea; border-radius: 4px; flex-shrink: 0; }
.file-act:hover { background: #f0f3ff; }
.file-del { color: #dc2626; }
.file-del:hover { background: #fff1f1 !important; }
</style>

<style>
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.35);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.modal {
  background: white; border-radius: 14px; width: 100%; max-width: 480px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.15); max-height: 90vh; overflow-y: auto;
}
.modal.modal-sm { max-width: 380px; }
.dropdown-fixed {
  position: fixed; background: white; border: 1px solid #e2e8f0;
  border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.12);
  z-index: 9999; min-width: 130px; overflow: hidden;
}
.dropdown-fixed button {
  display: block; width: 100%; text-align: left; padding: 9px 14px;
  font-size: 13px; background: none; border: none; cursor: pointer; color: #374151;
}
.dropdown-fixed button:hover { background: #f8fafc; }
.dropdown-fixed .drop-danger { color: #dc2626; }
.dropdown-fixed .drop-danger:hover { background: #fff1f1; }
</style>
