<!--
|--------------------------------------------------------------------------
| DevVerificacoesTab.vue — Revisão sênior por área (CRUD + drag-drop)
|--------------------------------------------------------------------------
| Lista sessão-a-sessão de verificações de qualidade de código por área do
| sistema. Diferente da Auditoria (bugs conhecidos), aqui registramos o que
| já foi revisado, o que falta revisar, e o resultado de cada revisão.
-->
<script setup>
import { ref, computed, onMounted } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import ConfirmDialog from 'primevue/confirmdialog';
import DevDrawer from './components/DevDrawer.vue';
import DevField from './components/DevField.vue';
import { useDraggableList, reorderWithIndexes } from './composables/useDraggableList';

const toast = useToast();
const confirm = useConfirm();

const loading = ref(true);
const items = ref([]);
const filterArea = ref('all');
const filterStatus = ref('all');
const filterSev = ref('all');
const search = ref('');
const openRow = ref(null);

const drawerOpen = ref(false);
const saving = ref(false);
const editingId = ref(null);
const form = ref(emptyForm());

function emptyForm() {
    return {
        area: '',
        categoria: '',
        titulo: '',
        descricao: '',
        resultado: '',
        acao_sugerida: '',
        severidade: '',
        status: 'pendente',
        verificado_em: null,
        sessao_verificacao: '',
        arquivo_afetado: '',
        auditoria_item_id: null,
        tags: ''
    };
}

const STATUS_LABEL = {
    pendente:    { label: 'Pendente',    color: '#94a3b8', bg: 'rgba(148,163,184,.12)', icon: 'pi-hourglass' },
    verificando: { label: 'Verificando', color: '#0ea5e9', bg: 'rgba(14,165,233,.12)',  icon: 'pi-search' },
    ok:          { label: 'OK',          color: '#10b981', bg: 'rgba(16,185,129,.12)',  icon: 'pi-check-circle' },
    problema:    { label: 'Problema',    color: '#ef4444', bg: 'rgba(239,68,68,.12)',   icon: 'pi-exclamation-triangle' },
    corrigido:   { label: 'Corrigido',   color: '#8b5cf6', bg: 'rgba(139,92,246,.12)',  icon: 'pi-verified' },
    wontfix:     { label: "Won't fix",   color: '#64748b', bg: 'rgba(100,116,139,.12)', icon: 'pi-ban' }
};

const SEV_LABEL = {
    critico: { label: 'Crítico', color: '#dc2626' },
    alto:    { label: 'Alto',    color: '#f59e0b' },
    medio:   { label: 'Médio',   color: '#0ea5e9' },
    baixo:   { label: 'Baixo',   color: '#94a3b8' }
};

// Áreas sugeridas — usuário pode digitar livre também
const AREA_SUGGESTIONS = [
    'auth', 'router', 'session',
    'agenda', 'pacientes', 'financeiro', 'documentos',
    'comunicacao', 'notificacoes', 'whatsapp',
    'saas-admin', 'billing', 'portal',
    'stores', 'composables', 'ui-shared',
    'database', 'rls', 'migrations',
    'performance', 'seguranca', 'observabilidade'
];

async function load() {
    loading.value = true;
    try {
        const { data, error } = await supabase
            .from('dev_verificacoes_items')
            .select('*')
            .order('area')
            .order('ordem')
            .order('created_at', { ascending: false });
        if (error) throw error;
        items.value = data || [];
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
    } finally {
        loading.value = false;
    }
}

const areasList = computed(() => {
    const set = new Set();
    items.value.forEach((i) => i.area && set.add(i.area));
    AREA_SUGGESTIONS.forEach((a) => set.add(a));
    return Array.from(set).sort();
});

const itemsFiltered = computed(() => {
    let list = items.value;
    if (filterArea.value !== 'all') list = list.filter((i) => i.area === filterArea.value);
    if (filterStatus.value !== 'all') list = list.filter((i) => i.status === filterStatus.value);
    if (filterSev.value !== 'all') list = list.filter((i) => i.severidade === filterSev.value);
    if (search.value.trim()) {
        const q = search.value.toLowerCase();
        list = list.filter(
            (i) =>
                i.titulo.toLowerCase().includes(q) ||
                (i.descricao || '').toLowerCase().includes(q) ||
                (i.resultado || '').toLowerCase().includes(q) ||
                (i.categoria || '').toLowerCase().includes(q) ||
                (i.area || '').toLowerCase().includes(q)
        );
    }
    return list;
});

const counts = computed(() => ({
    total: items.value.length,
    pendente: items.value.filter((i) => i.status === 'pendente').length,
    verificando: items.value.filter((i) => i.status === 'verificando').length,
    ok: items.value.filter((i) => i.status === 'ok').length,
    problema: items.value.filter((i) => i.status === 'problema').length,
    corrigido: items.value.filter((i) => i.status === 'corrigido').length
}));

function toggle(id) {
    openRow.value = openRow.value === id ? null : id;
}

function formatDate(iso) {
    if (!iso) return '—';
    return new Date(iso).toLocaleDateString('pt-BR');
}

// ── CRUD ────────────────────────────────────────────────────────
function openNew() {
    editingId.value = null;
    form.value = emptyForm();
    if (filterArea.value !== 'all') form.value.area = filterArea.value;
    drawerOpen.value = true;
}

function openEdit(item) {
    editingId.value = item.id;
    form.value = {
        area: item.area || '',
        categoria: item.categoria || '',
        titulo: item.titulo || '',
        descricao: item.descricao || '',
        resultado: item.resultado || '',
        acao_sugerida: item.acao_sugerida || '',
        severidade: item.severidade || '',
        status: item.status || 'pendente',
        verificado_em: item.verificado_em || null,
        sessao_verificacao: item.sessao_verificacao || '',
        arquivo_afetado: item.arquivo_afetado || '',
        auditoria_item_id: item.auditoria_item_id || null,
        tags: (item.tags || []).join(', ')
    };
    drawerOpen.value = true;
}

async function save() {
    if (!form.value.titulo.trim()) {
        toast.add({ severity: 'warn', summary: 'Título obrigatório', life: 3000 });
        return;
    }
    if (!form.value.area.trim()) {
        toast.add({ severity: 'warn', summary: 'Área obrigatória', life: 3000 });
        return;
    }
    saving.value = true;
    try {
        const payload = {
            area: form.value.area.trim(),
            categoria: form.value.categoria.trim() || null,
            titulo: form.value.titulo.trim(),
            descricao: form.value.descricao.trim() || null,
            resultado: form.value.resultado.trim() || null,
            acao_sugerida: form.value.acao_sugerida.trim() || null,
            severidade: form.value.severidade || null,
            status: form.value.status,
            verificado_em: form.value.verificado_em || null,
            sessao_verificacao: form.value.sessao_verificacao.trim() || null,
            arquivo_afetado: form.value.arquivo_afetado.trim() || null,
            auditoria_item_id: form.value.auditoria_item_id || null,
            tags: form.value.tags
                ? form.value.tags.split(',').map((t) => t.trim()).filter(Boolean)
                : []
        };

        if (editingId.value) {
            const { error } = await supabase.from('dev_verificacoes_items').update(payload).eq('id', editingId.value);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Salvo', life: 2000 });
        } else {
            payload.ordem = (items.value.filter((i) => i.area === payload.area).length || 0) + 1;
            const { error } = await supabase.from('dev_verificacoes_items').insert(payload);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Criado', life: 2000 });
        }
        drawerOpen.value = false;
        await load();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 4000 });
    } finally {
        saving.value = false;
    }
}

function askDelete() {
    if (!editingId.value) return;
    confirm.require({
        message: 'Tem certeza que quer excluir este item?',
        header: 'Confirmar exclusão',
        icon: 'pi pi-exclamation-triangle',
        acceptClass: 'p-button-danger',
        accept: async () => {
            try {
                const { error } = await supabase.from('dev_verificacoes_items').delete().eq('id', editingId.value);
                if (error) throw error;
                toast.add({ severity: 'success', summary: 'Excluído', life: 2000 });
                drawerOpen.value = false;
                await load();
            } catch (e) {
                toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
            }
        }
    });
}

// ── Drag & drop ───────────────────────────────────────────────────
async function handleReorder(fromIdx, toIdx) {
    const hasFilter = filterArea.value !== 'all' || filterStatus.value !== 'all' || filterSev.value !== 'all' || search.value.trim();
    if (hasFilter) {
        toast.add({
            severity: 'warn',
            summary: 'Limpe os filtros pra reordenar',
            detail: 'Drag-drop só funciona com a lista completa.',
            life: 3500
        });
        return;
    }
    const before = items.value;
    items.value = reorderWithIndexes(before, fromIdx, toIdx);
    try {
        const updates = items.value.map((item) =>
            supabase.from('dev_verificacoes_items').update({ ordem: item.ordem }).eq('id', item.id)
        );
        await Promise.all(updates);
    } catch (e) {
        items.value = before;
        toast.add({ severity: 'error', summary: 'Erro ao reordenar', detail: e.message, life: 4000 });
    }
}

const drag = useDraggableList({ onReorder: handleReorder });

onMounted(load);
</script>

<template>
    <ConfirmDialog />

    <div v-if="loading" class="loading">
        <i class="pi pi-spin pi-spinner text-2xl text-indigo-500" />
    </div>

    <div v-else class="verificacoes">
        <!-- Stats -->
        <div class="stats">
            <div class="stat">
                <span class="stat-num">{{ counts.total }}</span>
                <span class="stat-lbl">total</span>
            </div>
            <div class="stat" style="--c: #94a3b8">
                <span class="stat-num">{{ counts.pendente }}</span>
                <span class="stat-lbl">pendentes</span>
            </div>
            <div class="stat" style="--c: #0ea5e9">
                <span class="stat-num">{{ counts.verificando }}</span>
                <span class="stat-lbl">verificando</span>
            </div>
            <div class="stat" style="--c: #10b981">
                <span class="stat-num">{{ counts.ok }}</span>
                <span class="stat-lbl">OK</span>
            </div>
            <div class="stat" style="--c: #ef4444">
                <span class="stat-num">{{ counts.problema }}</span>
                <span class="stat-lbl">com problema</span>
            </div>
            <div class="stat" style="--c: #8b5cf6">
                <span class="stat-num">{{ counts.corrigido }}</span>
                <span class="stat-lbl">corrigidos</span>
            </div>
        </div>

        <!-- Toolbar -->
        <div class="toolbar">
            <input v-model="search" type="search" placeholder="Buscar..." class="filter-search" />
            <select v-model="filterArea" class="filter-sel">
                <option value="all">Todas áreas</option>
                <option v-for="a in areasList" :key="a" :value="a">{{ a }}</option>
            </select>
            <select v-model="filterStatus" class="filter-sel">
                <option value="all">Todos os status</option>
                <option value="pendente">Pendente</option>
                <option value="verificando">Verificando</option>
                <option value="ok">OK</option>
                <option value="problema">Problema</option>
                <option value="corrigido">Corrigido</option>
                <option value="wontfix">Won't fix</option>
            </select>
            <select v-model="filterSev" class="filter-sel">
                <option value="all">Todas severidades</option>
                <option value="critico">Crítico</option>
                <option value="alto">Alto</option>
                <option value="medio">Médio</option>
                <option value="baixo">Baixo</option>
            </select>
            <button class="btn-primary" @click="openNew">
                <i class="pi pi-plus" /> Novo item
            </button>
        </div>

        <!-- Lista -->
        <div v-if="!itemsFiltered.length" class="empty">
            Nenhum item com os filtros atuais.
        </div>

        <div v-else class="list">
            <article
                v-for="(item, idx) in itemsFiltered"
                :key="item.id"
                :class="[
                    'verif-item',
                    { open: openRow === item.id, dragging: drag.dragIdx.value === idx, 'drop-target': drag.overIdx.value === idx && drag.dragIdx.value !== idx }
                ]"
                draggable="true"
                @dragstart="drag.onDragStart($event, idx)"
                @dragover.prevent="drag.onDragOver($event, idx)"
                @drop="drag.onDrop($event, idx)"
                @dragend="drag.onDragEnd"
            >
                <header class="verif-head">
                    <span class="drag-handle" title="Arrastar pra reordenar">
                        <i class="pi pi-bars" />
                    </span>
                    <i
                        :class="['pi', STATUS_LABEL[item.status]?.icon || 'pi-circle']"
                        :style="{ color: STATUS_LABEL[item.status]?.color }"
                    />
                    <div class="verif-title-wrap" @click="toggle(item.id)">
                        <h4 class="verif-title">
                            <span class="verif-ref">V#{{ item.id }}</span>
                            <span class="verif-area">{{ item.area }}</span>
                            {{ item.titulo }}
                        </h4>
                        <div class="verif-meta">
                            <span v-if="item.categoria" class="verif-cat">{{ item.categoria }}</span>
                            <span v-if="item.severidade" :style="{ color: SEV_LABEL[item.severidade]?.color }">
                                {{ SEV_LABEL[item.severidade]?.label }}
                            </span>
                            <span v-if="item.arquivo_afetado" class="verif-file">
                                <i class="pi pi-file text-xs" /> {{ item.arquivo_afetado }}
                            </span>
                        </div>
                    </div>
                    <span
                        class="verif-status"
                        :style="{ color: STATUS_LABEL[item.status]?.color, background: STATUS_LABEL[item.status]?.bg }"
                    >{{ STATUS_LABEL[item.status]?.label }}</span>
                    <button class="btn-icon" @click="openEdit(item)" title="Editar">
                        <i class="pi pi-pencil" />
                    </button>
                    <i
                        :class="['pi pi-chevron-down verif-chev', { open: openRow === item.id }]"
                        @click="toggle(item.id)"
                    />
                </header>

                <div v-if="openRow === item.id" class="verif-body">
                    <div v-if="item.descricao" class="verif-section">
                        <h5>O que verificar</h5>
                        <p>{{ item.descricao }}</p>
                    </div>
                    <div v-if="item.resultado" class="verif-section">
                        <h5>Resultado</h5>
                        <p>{{ item.resultado }}</p>
                    </div>
                    <div v-if="item.acao_sugerida" class="verif-section">
                        <h5>Ação sugerida</h5>
                        <p>{{ item.acao_sugerida }}</p>
                    </div>
                    <div v-if="item.sessao_verificacao || item.verificado_em" class="verif-section">
                        <h5>Verificação</h5>
                        <p>
                            <span v-if="item.sessao_verificacao">{{ item.sessao_verificacao }}</span>
                            <span v-if="item.verificado_em" class="text-[var(--text-color-secondary)]">
                                — {{ formatDate(item.verificado_em) }}
                            </span>
                        </p>
                    </div>
                    <div v-if="item.auditoria_item_id" class="verif-section">
                        <h5>Vinculado à Auditoria</h5>
                        <p>#{{ item.auditoria_item_id }}</p>
                    </div>
                    <div v-if="item.tags && item.tags.length" class="verif-tags">
                        <span v-for="tag in item.tags" :key="tag" class="tag">#{{ tag }}</span>
                    </div>
                </div>
            </article>
        </div>

        <!-- Drawer de edição -->
        <DevDrawer
            :open="drawerOpen"
            :title="editingId ? 'Editar verificação' : 'Nova verificação'"
            :subtitle="editingId ? `#${editingId}` : 'Preencha os campos e salve'"
            :can-save="!!form.titulo.trim() && !!form.area.trim()"
            :saving="saving"
            :danger="!!editingId"
            @close="drawerOpen = false"
            @save="save"
            @delete="askDelete"
        >
            <div class="form-row">
                <DevField label="Área" required hint="Ex.: auth, agenda, financeiro">
                    <input v-model="form.area" list="area-suggestions" placeholder="área" />
                    <datalist id="area-suggestions">
                        <option v-for="a in AREA_SUGGESTIONS" :key="a" :value="a" />
                    </datalist>
                </DevField>

                <DevField label="Status">
                    <select v-model="form.status">
                        <option value="pendente">Pendente</option>
                        <option value="verificando">Verificando</option>
                        <option value="ok">OK</option>
                        <option value="problema">Problema</option>
                        <option value="corrigido">Corrigido</option>
                        <option value="wontfix">Won't fix</option>
                    </select>
                </DevField>
            </div>

            <DevField label="Título" required>
                <input v-model="form.titulo" placeholder="Ex.: Session refresh lock não libera em exceção" />
            </DevField>

            <div class="form-row">
                <DevField label="Severidade">
                    <select v-model="form.severidade">
                        <option value="">—</option>
                        <option value="critico">Crítico</option>
                        <option value="alto">Alto</option>
                        <option value="medio">Médio</option>
                        <option value="baixo">Baixo</option>
                    </select>
                </DevField>

                <DevField label="Categoria" hint="Ex.: Performance, Segurança, DX">
                    <input v-model="form.categoria" placeholder="Categoria" />
                </DevField>
            </div>

            <DevField label="O que verificar" hint="Descrição do que precisa ser analisado nessa área">
                <textarea v-model="form.descricao" rows="3" />
            </DevField>

            <DevField label="Resultado" hint="O que foi encontrado ao verificar">
                <textarea v-model="form.resultado" rows="3" />
            </DevField>

            <DevField label="Ação sugerida" hint="Como tratar o que foi encontrado">
                <textarea v-model="form.acao_sugerida" rows="2" />
            </DevField>

            <div class="form-row">
                <DevField label="Data da verificação">
                    <input v-model="form.verificado_em" type="date" />
                </DevField>

                <DevField label="Sessão" hint="Ex.: Sessão 1 — auth/router">
                    <input v-model="form.sessao_verificacao" />
                </DevField>
            </div>

            <DevField label="Arquivo afetado" hint="src/features/agenda/...">
                <input v-model="form.arquivo_afetado" placeholder="Caminho do arquivo" />
            </DevField>

            <DevField label="Vínculo com Auditoria" hint="ID do item em dev_auditoria_items (se virou bug)">
                <input v-model.number="form.auditoria_item_id" type="number" placeholder="ID" />
            </DevField>

            <DevField label="Tags" hint="Separe por vírgula">
                <input v-model="form.tags" placeholder="tag1, tag2" />
            </DevField>
        </DevDrawer>
    </div>
</template>

<style scoped>
.loading { text-align: center; padding: 60px; }

.verificacoes { display: flex; flex-direction: column; gap: 12px; }

.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 10px;
}
.stat {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-left: 3px solid var(--c, var(--primary-color));
    border-radius: 8px;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
}
.stat-num { font-size: 22px; font-weight: 700; color: var(--text-color); line-height: 1; }
.stat-lbl { font-size: 11px; color: var(--text-color-secondary); margin-top: 4px; }

.toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.filter-search, .filter-sel {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-radius: 7px;
    padding: 7px 11px;
    font-size: 12px;
    color: var(--text-color);
    outline: none;
}
.filter-search { flex: 1; min-width: 200px; }
.filter-sel { min-width: 140px; cursor: pointer; }

.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--primary-color);
    color: white;
    border: none;
    border-radius: 7px;
    padding: 8px 13px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.15s;
}
.btn-primary:hover { opacity: 0.9; }

.list { display: flex; flex-direction: column; gap: 8px; }

.verif-item {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-radius: 8px;
    overflow: hidden;
    transition: all 0.15s;
}
.verif-item:hover { border-color: color-mix(in srgb, var(--primary-color) 30%, var(--surface-border)); }
.verif-item.dragging { opacity: 0.4; transform: scale(0.98); }
.verif-item.drop-target { border-color: var(--primary-color); border-style: dashed; background: color-mix(in srgb, var(--primary-color) 5%, transparent); }

.verif-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    user-select: none;
}

.drag-handle {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 4px;
    color: var(--text-color-secondary);
    cursor: grab;
    flex-shrink: 0;
    opacity: 0.5;
    transition: opacity 0.15s;
}
.drag-handle:hover { opacity: 1; background: var(--surface-ground); }
.drag-handle:active { cursor: grabbing; }

.verif-head > .pi:nth-child(2) { font-size: 16px; flex-shrink: 0; }

.verif-title-wrap { flex: 1; min-width: 0; cursor: pointer; }
.verif-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-color);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.verif-area {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
    padding: 2px 7px;
    border-radius: 4px;
}
.verif-ref {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-color-secondary);
    background: var(--surface-ground);
    padding: 2px 7px;
    border-radius: 4px;
    user-select: all;
}
.verif-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 11px;
    color: var(--text-color-secondary);
    margin-top: 3px;
}
.verif-cat {
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 600;
}
.verif-file {
    font-family: 'IBM Plex Mono', monospace;
    display: flex;
    align-items: center;
    gap: 4px;
}

.verif-status {
    font-size: 10px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 10px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    white-space: nowrap;
}

.btn-icon {
    background: transparent;
    border: none;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    color: var(--text-color-secondary);
    cursor: pointer;
    font-size: 12px;
    flex-shrink: 0;
    transition: all 0.15s;
}
.btn-icon:hover {
    background: var(--surface-ground);
    color: var(--primary-color);
}

.verif-chev {
    font-size: 11px;
    color: var(--text-color-secondary);
    transition: transform 0.2s;
    cursor: pointer;
    padding: 8px;
}
.verif-chev.open { transform: rotate(180deg); }

.verif-body {
    padding: 0 14px 14px 42px;
    border-top: 1px solid var(--surface-border);
    padding-top: 12px;
}
.verif-section { margin-bottom: 10px; }
.verif-section h5 {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-color-secondary);
    margin-bottom: 4px;
}
.verif-section p {
    font-size: 12px;
    line-height: 1.55;
    color: var(--text-color);
    margin: 0;
}

.verif-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.tag {
    font-size: 10px;
    font-family: 'IBM Plex Mono', monospace;
    color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
    padding: 2px 7px;
    border-radius: 4px;
}

.empty {
    text-align: center;
    padding: 40px;
    color: var(--text-color-secondary);
    background: var(--surface-card);
    border: 1px dashed var(--surface-border);
    border-radius: 10px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
</style>
