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

interface ApiEdital {
  ID: string
  Numero: string
  Orgao: string
  Modalidade: string
  Objeto: string
  Plataforma: string
  ValorEstimado: number
  DataPublicacao: string
  DataAbertura: string
  Status: string
}

interface ApiOrgao {
  ID: string
  Nome: string
  Esfera: string
  Estado: string
}

const { data: editais, refresh } = await useAsyncData('editais', () =>
  apiFetch<ApiEdital[]>('/editais')
)

const { data: orgaos } = await useAsyncData('orgaos-oportunidades', () =>
  apiFetch<ApiOrgao[]>('/organs'), { server: false }
)

// ---------- labels ----------
const MODALIDADE_LABEL: 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' },
}

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

function formatBRL(value: number): string {
  return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL', maximumFractionDigits: 0 }).format(value)
}


// ---------- 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 - 130 }
  menuAberto.value = menuAberto.value === id ? null : id
}
function fecharMenu() { menuAberto.value = null }

const router = useRouter()

function abrirVisualizar(edital: ApiEdital) {
  fecharMenu()
  router.push(`/oportunidades/${edital.ID}`)
}


// ---------- modal criar / editar ----------
const showModal = ref(false)
const editando = ref<ApiEdital | null>(null)
const saving = ref(false)
const erroModal = ref('')

const STATUS_OPTIONS = Object.entries(STATUS_CFG).map(([value, cfg]) => ({ value, label: cfg.label }))
const MODALIDADE_OPTIONS = Object.entries(MODALIDADE_LABEL).map(([value, label]) => ({ value, label }))

const form = ref({
  Numero: '',
  Orgao: '',
  Modalidade: 'pregao_eletronico',
  Objeto: '',
  Plataforma: '',
  ValorEstimado: 0,
  DataPublicacao: '',
  DataAbertura: '',
  Status: 'em_analise',
})

function abrirCriar() {
  editando.value = null
  erroModal.value = ''
  importedFile.value = null
  importedFileName.value = ''
  importError.value = ''
  form.value = {
    Numero: '', Orgao: '', Modalidade: 'pregao_eletronico',
    Objeto: '', Plataforma: '', ValorEstimado: 0,
    DataPublicacao: '', DataAbertura: '', Status: 'em_analise',
  }
  showModal.value = true
}

function abrirEditar(edital: ApiEdital) {
  fecharMenu()
  editando.value = edital
  erroModal.value = ''
  form.value = {
    Numero: edital.Numero,
    Orgao: edital.Orgao,
    Modalidade: edital.Modalidade,
    Objeto: edital.Objeto,
    Plataforma: edital.Plataforma,
    ValorEstimado: edital.ValorEstimado,
    DataPublicacao: edital.DataPublicacao.split('T')[0],
    DataAbertura: edital.DataAbertura.split('T')[0],
    Status: edital.Status,
  }
  showModal.value = true
}

async function salvar() {
  erroModal.value = ''
  saving.value = true
  try {
    let editalId: string | null = null

    if (editando.value) {
      await apiFetch(`/editais/${editando.value.ID}`, { method: 'PUT', body: form.value })
      editalId = editando.value.ID
    } else {
      const created = await apiFetch<ApiEdital>('/editais', { method: 'POST', body: form.value })
      editalId = created?.ID ?? null
    }

    // If this was a partial import, attach the PDF file to the created edital
    if (importedFile.value && editalId) {
      try {
        const formData = new FormData()
        formData.append('file', importedFile.value)
        await $fetch(`${apiBase}/editais/${editalId}/files`, {
          method: 'POST',
          headers: { Authorization: `Bearer ${token.value}` },
          body: formData,
        })
      } catch {
        // Non-fatal: edital was created, file attach failed silently
      }
      importedFile.value = null
      importedFileName.value = ''
    }

    showModal.value = false
    importError.value = ''
    await refresh()
  } catch {
    erroModal.value = 'Erro ao salvar edital.'
  } finally {
    saving.value = false
  }
}

// ---------- importar PDF ----------
const importLoading = ref(false)
const importError = ref('')
const importedFile = ref<File | null>(null)
const importedFileName = ref('')

async function importarEdital(event: Event) {
  const input = event.target as HTMLInputElement
  if (!input.files?.length) return

  const file = input.files[0]
  if (file.type !== 'application/pdf') {
    importError.value = 'Selecione um arquivo PDF.'
    return
  }

  importLoading.value = true
  importError.value = ''
  try {
    const formData = new FormData()
    formData.append('file', file)
    const res = await apiFetch<any>('/editais/import', {
      method: 'POST',
      body: formData,
    })

    // If backend returned partial data, open modal for manual completion
    if (res?.partial) {
      importedFile.value = file
      importedFileName.value = res.file_name || file.name
      editando.value = null
      erroModal.value = ''
      form.value = {
        Numero: res.numero || '',
        Orgao: res.orgao || '',
        Modalidade: res.modalidade || 'pregao_eletronico',
        Objeto: res.objeto || '',
        Plataforma: res.plataforma || '',
        ValorEstimado: res.valor_estimado || 0,
        DataPublicacao: res.data_publicacao || '',
        DataAbertura: res.data_abertura || '',
        Status: res.status || 'em_analise',
      }
      showModal.value = true
      const tipoLabel = res.tipo_documento === 'edital' ? 'Edital' : res.tipo_documento === 'termo_referencia' ? 'Termo de Referência' : 'Documento'
      importError.value = `⚠️ ${tipoLabel} detectado. Alguns campos precisam de revisão. Confira e complete manualmente.`
      return
    }

    await refresh()
  } catch (err: any) {
    importError.value = err?.data?.error || 'Erro ao importar edital do PDF.'
  } finally {
    importLoading.value = false
    input.value = ''
  }
}

// ---------- excluir ----------
const showDeleteConfirm = ref(false)
const deleteTarget = ref<ApiEdital | null>(null)
const deleting = ref(false)

function confirmarExclusao(edital: ApiEdital) {
  fecharMenu()
  deleteTarget.value = edital
  showDeleteConfirm.value = true
}

function cancelarExclusao() {
  showDeleteConfirm.value = false
  deleteTarget.value = null
}

async function executarExclusao() {
  if (!deleteTarget.value) return
  deleting.value = true
  try {
    await apiFetch(`/editais/${deleteTarget.value.ID}`, { method: 'DELETE' })
    showDeleteConfirm.value = false
    deleteTarget.value = null
    await refresh()
  } catch {
    // keep modal open on error
  } finally {
    deleting.value = false
  }
}
</script>

<template>
  <div class="page">
    <AppTopbar title="Todos os Editais" breadcrumb="Oportunidades · Todos">
      <template #actions>
        <label class="btn-import" :class="{ disabled: importLoading }">
          <input type="file" accept=".pdf" style="display:none" @change="importarEdital" />
          {{ importLoading ? '⏳ Importando…' : '📄 Importar Edital' }}
        </label>
        <button class="btn-primary" @click="abrirCriar">+ Nova Oportunidade</button>
      </template>
    </AppTopbar>

    <div class="content">
      <p v-if="importError" class="import-error">{{ importError }}</p>
      <div class="card">
        <table 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>
              <th></th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="!editais || editais.length === 0">
              <td colspan="8" class="empty">Nenhum edital cadastrado.</td>
            </tr>
            <tr v-for="e in editais" :key="e.ID">
              <td class="numero link" @click="router.push(`/oportunidades/${e.ID}`)">{{ e.Numero }}</td>
              <td>{{ e.Orgao }}</td>
              <td class="objeto">{{ e.Objeto }}</td>
              <td>{{ MODALIDADE_LABEL[e.Modalidade] ?? e.Modalidade }}</td>
              <td>{{ 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>
                <span v-else class="badge">{{ e.Status }}</span>
              </td>
              <td class="actions-cell">
                <button class="btn-menu" @click.stop="abrirMenu(e.ID, $event)">⋯</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- Dropdown menu -->
    <Teleport to="body">
      <div v-if="menuAberto" class="overlay-menu" @click="fecharMenu" />
      <div
        v-if="menuAberto"
        class="dropdown"
        :style="{ top: menuPos.top + 'px', left: menuPos.left + 'px' }"
      >
        <button @click="abrirVisualizar(editais!.find(e => e.ID === menuAberto)!)">Visualizar</button>
        <button @click="abrirEditar(editais!.find(e => e.ID === menuAberto)!)">Editar</button>
        <button class="drop-danger" @click="confirmarExclusao(editais!.find(e => e.ID === menuAberto)!)">Excluir</button>
      </div>
    </Teleport>

    <!-- Modal criar / editar -->
    <Teleport to="body">
      <div v-if="showModal" class="modal-overlay" @click.self="showModal = false">
        <div class="modal">
          <div class="modal-header">
            <h3>{{ editando ? 'Editar Edital' : importedFile ? 'Completar Importação' : 'Nova Oportunidade' }}</h3>
            <button class="close-btn" @click="showModal = false; importedFile = null; importedFileName = ''; importError = ''">✕</button>
          </div>
          <div class="modal-body">
            <!-- Import partial notice -->
            <div v-if="importedFile" class="import-notice">
              <span class="import-notice-icon">📄</span>
              <div>
                <strong>Importado do PDF:</strong> {{ importedFileName }}
                <p>A IA extraiu os dados abaixo. Complete os campos que ficaram vazios e confira os preenchidos.</p>
              </div>
            </div>
            <div class="form-row">
              <div class="field">
                <label>Nº do Edital / Processo *</label>
                <input v-model="form.Numero" class="inp" placeholder="PE 001/2026" />
              </div>
              <div class="field">
                <label>Órgão Público *</label>
                <select v-model="form.Orgao" class="inp">
                  <option value="" disabled>Selecione o órgão</option>
                  <option v-for="o in orgaos" :key="o.ID" :value="o.Nome">{{ o.Nome }}</option>
                </select>
              </div>
            </div>
            <div class="field">
              <label>Objeto</label>
              <input v-model="form.Objeto" class="inp" placeholder="Descrição do objeto licitado" />
            </div>
            <div class="form-row">
              <div class="field">
                <label>Modalidade *</label>
                <select v-model="form.Modalidade" class="inp">
                  <option v-for="opt in MODALIDADE_OPTIONS" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
                </select>
              </div>
              <div class="field">
                <label>Plataforma</label>
                <input v-model="form.Plataforma" class="inp" placeholder="Compras.gov.br" />
              </div>
            </div>
            <div class="form-row">
              <div class="field">
                <label>Valor Estimado (R$)</label>
                <input v-model.number="form.ValorEstimado" type="number" min="0" step="0.01" class="inp" />
              </div>
              <div class="field">
                <label>Status *</label>
                <select v-model="form.Status" class="inp">
                  <option v-for="opt in STATUS_OPTIONS" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
                </select>
              </div>
            </div>
            <div class="form-row">
              <div class="field">
                <label>Data Publicação *</label>
                <input v-model="form.DataPublicacao" type="date" class="inp" />
              </div>
              <div class="field">
                <label>Data Abertura *</label>
                <input v-model="form.DataAbertura" type="date" class="inp" />
              </div>
            </div>
            <p v-if="erroModal" class="erro-msg">{{ erroModal }}</p>
          </div>
          <div class="modal-footer">
            <button class="btn-cancel" @click="showModal = false">Cancelar</button>
            <button class="btn-save" :disabled="saving" @click="salvar">
              {{ saving ? 'Salvando…' : 'Salvar' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- Delete confirmation modal -->
    <Teleport to="body">
      <div v-if="showDeleteConfirm" class="modal-overlay" @click.self="cancelarExclusao">
        <div class="modal-delete">
          <div class="modal-delete-icon">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
              <polyline points="3 6 5 6 21 6"/>
              <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
              <line x1="10" y1="11" x2="10" y2="17"/>
              <line x1="14" y1="11" x2="14" y2="17"/>
            </svg>
          </div>
          <h3 class="modal-delete-title">Excluir Oportunidade</h3>
          <p class="modal-delete-text">
            Tem certeza que deseja excluir o edital
            <strong>{{ deleteTarget?.Numero }}</strong>?
            <br/>Esta ação não pode ser desfeita.
          </p>
          <div class="modal-delete-actions">
            <button class="btn-cancel" @click="cancelarExclusao">Cancelar</button>
            <button class="btn-delete" :disabled="deleting" @click="executarExclusao">
              {{ deleting ? 'Excluindo…' : 'Sim, 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; }

.btn-import {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white; border: none; border-radius: 7px;
  padding: 7px 16px; font-size: 13px; font-weight: 600; cursor: pointer;
  margin-right: 8px;
}
.btn-import:hover { opacity: 0.9; }
.btn-import.disabled { opacity: 0.6; pointer-events: none; }

.btn-primary {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white; border: none; border-radius: 7px;
  padding: 7px 16px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.btn-primary:hover { opacity: 0.9; }

.import-error {
  background: #fef2f2; color: #dc2626; border: 1px solid #fecaca;
  border-radius: 8px; padding: 10px 16px; font-size: 13px; margin-bottom: 12px;
}

/* table */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl thead tr { border-bottom: 1px solid #e2e8f0; background: #f8fafc; }
.tbl th { padding: 10px 14px; text-align: left; font-weight: 600; color: #64748b; font-size: 12px; text-transform: uppercase; letter-spacing: .4px; white-space: nowrap; }
.tbl td { padding: 11px 14px; color: #1e293b; border-bottom: 1px solid #f1f5f9; vertical-align: middle; }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl tbody tr:hover td { background: #f8fafc; }
.numero { font-weight: 600; white-space: nowrap; }
.numero.link { color: #667eea; cursor: pointer; }
.numero.link:hover { color: #764ba2; text-decoration: underline; }
.objeto { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empty { text-align: center; color: #94a3b8; padding: 40px; }
.actions-cell { text-align: right; white-space: nowrap; }
.btn-menu { background: none; border: none; cursor: pointer; font-size: 18px; color: #94a3b8; padding: 2px 6px; border-radius: 4px; }
.btn-menu:hover { background: #f1f5f9; color: #475569; }
.badge { display: inline-block; padding: 3px 9px; border-radius: 20px; font-size: 11.5px; font-weight: 600; }

/* dropdown */
.overlay-menu { position: fixed; inset: 0; z-index: 999; }
.dropdown { position: fixed; z-index: 1000; background: white; border: 1px solid #e2e8f0; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,.12); min-width: 140px; overflow: hidden; }
.dropdown button { display: block; width: 100%; padding: 9px 14px; text-align: left; background: none; border: none; cursor: pointer; font-size: 13px; color: #334155; }
.dropdown button:hover { background: #f8fafc; }
.drop-danger { color: #dc2626 !important; }

/* modal */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 1000; display: flex; align-items: center; justify-content: center; }
.modal { background: white; border-radius: 12px; width: 600px; max-width: 95vw; max-height: 90vh; overflow-y: auto; box-shadow: 0 8px 40px rgba(0,0,0,.2); }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; border-bottom: 1px solid #e2e8f0; }
.modal-header h3 { margin: 0; font-size: 15px; font-weight: 700; color: #1e293b; }
.close-btn { background: none; border: none; cursor: pointer; font-size: 16px; color: #64748b; }
.modal-body { padding: 20px 22px; display: flex; flex-direction: column; gap: 18px; }
.modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 22px; border-top: 1px solid #f1f5f9; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 12px; font-weight: 600; color: #475569; }
.inp { border: 1px solid #e2e8f0; border-radius: 7px; padding: 8px 10px; font-size: 13px; color: #1e293b; width: 100%; box-sizing: border-box; }
.inp:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102,126,234,.1); }
.btn-cancel { background: #f1f5f9; color: #475569; border: none; border-radius: 7px; padding: 8px 18px; font-size: 13px; font-weight: 600; cursor: pointer; }
.btn-save { background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; border-radius: 7px; padding: 8px 18px; font-size: 13px; font-weight: 600; cursor: pointer; }
.btn-save:disabled { opacity: .6; cursor: not-allowed; }
.erro-msg { color: #dc2626; font-size: 12px; margin: 0; }

/* delete confirm modal */
.modal-delete {
  background: white; border-radius: 16px;
  width: 400px; max-width: 90vw;
  padding: 32px 28px 24px;
  box-shadow: 0 20px 60px rgba(0,0,0,.25);
  text-align: center;
  animation: modalPopIn .2s ease;
}
@keyframes modalPopIn {
  from { opacity: 0; transform: scale(.92); }
  to { opacity: 1; transform: scale(1); }
}
.modal-delete-icon {
  width: 56px; height: 56px; border-radius: 50%;
  background: #fef2f2; color: #dc2626;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 16px;
}
.modal-delete-title {
  font-size: 16px; font-weight: 700; color: #0f172a;
  margin: 0 0 8px;
}
.modal-delete-text {
  font-size: 13.5px; color: #64748b; line-height: 1.6;
  margin: 0 0 24px;
}
.modal-delete-text strong { color: #1e293b; }
.modal-delete-actions {
  display: flex; gap: 10px; justify-content: center;
}
.btn-delete {
  background: #dc2626; color: white;
  border: none; border-radius: 9px;
  padding: 9px 22px; font-size: 13px; font-weight: 700;
  cursor: pointer; transition: all .15s;
}
.btn-delete:hover { background: #b91c1c; }
.btn-delete:disabled { opacity: .5; cursor: not-allowed; }

/* import notice */
.import-notice {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px; border-radius: 10px;
  background: #eff6ff; border: 1px solid #bfdbfe;
  margin-bottom: 4px;
}
.import-notice-icon { font-size: 24px; flex-shrink: 0; margin-top: 2px; }
.import-notice strong { font-size: 13px; color: #1e40af; }
.import-notice p { font-size: 12px; color: #3b82f6; margin: 4px 0 0; line-height: 1.4; }

</style>
