<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { Head, router } from '@inertiajs/vue3'
import axios from 'axios'
import AdminLayout from '@/Layouts/AdminLayout.vue'
import {
    CpuChipIcon,
    CircleStackIcon,
    Squares2X2Icon,
    ArrowPathIcon,
    MagnifyingGlassIcon,
    XMarkIcon,
    ExclamationTriangleIcon,
    ChevronUpIcon,
    ChevronDownIcon,
    PlayIcon,
    PauseIcon,
} from '@heroicons/vue/24/outline'

const props = defineProps({
    processes: { type: Array, default: () => [] },
    totals: { type: Object, default: () => ({ total: 0, running: 0, sleeping: 0, zombie: 0, stopped: 0 }) },
    load: { type: Object, default: () => ({ '1m': 0, '5m': 0, '15m': 0, cores: 1 }) },
    aggregates: { type: Object, default: () => ({ count: 0, total_cpu_pct: 0, total_mem_mb: 0 }) },
    top_users: { type: Array, default: () => [] },
    distinct_users: { type: Array, default: () => [] },
    filters: { type: Object, default: () => ({}) },
})

// ── State ────────────────────────────────────────────────────────────────────
const list = ref([...props.processes])
const totals = ref({ ...props.totals })
const load = ref({ ...props.load })
const aggregates = ref({ ...props.aggregates })
const topUsers = ref([...props.top_users])
const distinctUsers = ref([...props.distinct_users])

const filters = ref({
    user: props.filters?.user ?? '',
    min_cpu: Number(props.filters?.min_cpu ?? 0),
    min_mem_mb: Number(props.filters?.min_mem_mb ?? 0),
    search: props.filters?.search ?? '',
    sort: props.filters?.sort ?? 'cpu',
    direction: props.filters?.direction ?? 'desc',
    limit: Number(props.filters?.limit ?? 50),
})

const autoRefresh = ref(true)
const refreshing = ref(false)
const lastRefreshed = ref(new Date())

// ── Kill modal ───────────────────────────────────────────────────────────────
const killModal = ref({ open: false, process: null, force: false, reason: '', submitting: false })

const openKillModal = (p) => {
    killModal.value = { open: true, process: p, force: false, reason: '', submitting: false }
}
const closeKillModal = () => {
    killModal.value.open = false
}
const confirmKill = () => {
    const p = killModal.value.process
    if (!p) return
    killModal.value.submitting = true
    router.post(
        route('admin.processes.kill', p.pid),
        {
            signal: killModal.value.force ? 'KILL' : 'TERM',
            force: killModal.value.force,
            reason: killModal.value.reason,
        },
        {
            preserveScroll: true,
            onFinish: () => {
                killModal.value.submitting = false
                closeKillModal()
                refresh()
            },
        },
    )
}

// ── Auto-refresh (5s polling) ────────────────────────────────────────────────
let pollTimer = null

const refresh = async () => {
    if (refreshing.value) return
    refreshing.value = true
    try {
        // `admin.processes.live` yeni isim; mevcut routes/web.php hala `refresh` kullanıyor.
        // Ziggy fallback: yeni route varsa onu kullan, yoksa eski .refresh adına düş.
        const routeName = (typeof route !== 'undefined' && route().has && route().has('admin.processes.live'))
            ? 'admin.processes.live'
            : 'admin.processes.refresh'
        const { data } = await axios.get(route(routeName), { params: filters.value })
        list.value = data.processes ?? []
        totals.value = data.totals ?? totals.value
        load.value = data.load ?? load.value
        aggregates.value = data.aggregates ?? aggregates.value
        topUsers.value = data.top_users ?? topUsers.value
        distinctUsers.value = data.distinct_users ?? distinctUsers.value
        lastRefreshed.value = new Date()
    } catch (e) {
        // sessizce yut — polling fail olabilir
    } finally {
        refreshing.value = false
    }
}

onMounted(() => {
    pollTimer = setInterval(() => {
        if (autoRefresh.value) refresh()
    }, 5000)
})
onBeforeUnmount(() => {
    if (pollTimer) clearInterval(pollTimer)
    pollTimer = null
})

// ── Sort UI ──────────────────────────────────────────────────────────────────
const setSort = (col) => {
    if (filters.value.sort === col) {
        filters.value.direction = filters.value.direction === 'desc' ? 'asc' : 'desc'
    } else {
        filters.value.sort = col
        filters.value.direction = 'desc'
    }
    refresh()
}

const onFilterChange = () => refresh()

const resetFilters = () => {
    filters.value = { user: '', min_cpu: 0, min_mem_mb: 0, search: '', sort: 'cpu', direction: 'desc', limit: 50 }
    refresh()
}

// ── Helpers ──────────────────────────────────────────────────────────────────
const isProtected = (p) => {
    if ((p.pid ?? 0) < 100) return true
    const cmd = String(p.args || p.cmd || '').toLowerCase()
    return /\b(systemd|init|sshd|kernel|kthreadd|systemd-journald|systemd-logind|systemd-udevd|apache2?|httpd|nginx|php-fpm)\b/.test(cmd)
}

const rowClass = (p) => {
    const cpu = Number(p.cpu_pct ?? p.cpu ?? 0)
    if (cpu > 80) return 'bg-red-50 hover:bg-red-100'
    if (cpu >= 50) return 'bg-amber-50 hover:bg-amber-100'
    return 'hover:bg-slate-50'
}

const truncate = (s, n = 80) => {
    const str = String(s ?? '')
    return str.length > n ? str.slice(0, n) + '…' : str
}

const formatNumber = (n, d = 1) => Number(n ?? 0).toFixed(d)

const loadColor = (l) => {
    const cores = load.value.cores || 1
    if (l > cores) return 'text-red-600 font-semibold'
    if (l > cores * 0.7) return 'text-amber-600 font-semibold'
    return 'text-emerald-600'
}

const stateLabel = (s) => ({
    R: 'Çalışıyor',
    S: 'Uyuyor',
    D: 'Disk Bekliyor',
    Z: 'Zombi',
    T: 'Durdurulmuş',
}[s] || s)

const lastRefreshLabel = computed(() => {
    const d = lastRefreshed.value
    const hh = String(d.getHours()).padStart(2, '0')
    const mm = String(d.getMinutes()).padStart(2, '0')
    const ss = String(d.getSeconds()).padStart(2, '0')
    return `${hh}:${mm}:${ss}`
})

const sortIcon = (col) => {
    if (filters.value.sort !== col) return null
    return filters.value.direction === 'asc' ? ChevronUpIcon : ChevronDownIcon
}
</script>

<template>
    <Head title="Süreç Yöneticisi" />
    <AdminLayout>
        <template #header>
            <div class="flex items-center justify-between">
                <span>Süreç Yöneticisi (Process Manager)</span>
                <div class="flex items-center gap-3 text-sm">
                    <span class="text-xs text-slate-500">Son güncelleme: {{ lastRefreshLabel }}</span>
                    <label class="inline-flex items-center gap-2 text-xs">
                        <input v-model="autoRefresh" type="checkbox" class="rounded border-slate-300" />
                        <span class="flex items-center gap-1">
                            <PlayIcon v-if="autoRefresh" class="h-3.5 w-3.5 text-emerald-600" />
                            <PauseIcon v-else class="h-3.5 w-3.5 text-slate-400" />
                            Otomatik yenile (5sn)
                        </span>
                    </label>
                    <button @click="refresh"
                            :disabled="refreshing"
                            class="inline-flex items-center gap-1 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-xs hover:bg-slate-50 disabled:opacity-50">
                        <ArrowPathIcon class="h-3.5 w-3.5" :class="{ 'animate-spin': refreshing }" />
                        Yenile
                    </button>
                </div>
            </div>
        </template>

        <!-- ── Stat cards (3) ──────────────────────────────────────────────── -->
        <div class="mb-4 grid grid-cols-1 gap-3 md:grid-cols-3">
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-slate-500">
                    <Squares2X2Icon class="h-5 w-5 text-indigo-500" />
                    <span class="text-xs uppercase tracking-wide">Toplam İşlem</span>
                </div>
                <div class="mt-1 text-3xl font-bold text-slate-900">{{ aggregates.count }}</div>
                <p class="mt-1 text-xs text-slate-500">
                    Sistem toplamı: {{ totals.total }} · Çalışan: {{ totals.running }} · Uyuyor: {{ totals.sleeping }}
                </p>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-slate-500">
                    <CpuChipIcon class="h-5 w-5 text-amber-500" />
                    <span class="text-xs uppercase tracking-wide">Toplam CPU</span>
                </div>
                <div class="mt-1 text-3xl font-bold text-slate-900">{{ formatNumber(aggregates.total_cpu_pct, 1) }}%</div>
                <p class="mt-1 text-xs text-slate-500">
                    Load: <span :class="loadColor(load['1m'])">{{ formatNumber(load['1m'], 2) }}</span>
                    / <span :class="loadColor(load['5m'])">{{ formatNumber(load['5m'], 2) }}</span>
                    / <span :class="loadColor(load['15m'])">{{ formatNumber(load['15m'], 2) }}</span>
                    ({{ load.cores }} çekirdek)
                </p>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-slate-500">
                    <CircleStackIcon class="h-5 w-5 text-emerald-500" />
                    <span class="text-xs uppercase tracking-wide">Toplam RAM</span>
                </div>
                <div class="mt-1 text-3xl font-bold text-slate-900">{{ formatNumber(aggregates.total_mem_mb, 0) }} MB</div>
                <p class="mt-1 text-xs text-slate-500">Listelenen işlemlerin RSS toplamı</p>
            </div>
        </div>

        <!-- ── Top 5 users by CPU ─────────────────────────────────────────── -->
        <div class="mb-4 rounded-xl border border-slate-200 bg-white shadow-sm">
            <div class="border-b border-slate-200 px-4 py-2">
                <h3 class="text-sm font-semibold text-slate-700">CPU'ya Göre İlk 5 Kullanıcı</h3>
            </div>
            <table class="min-w-full divide-y divide-slate-100 text-xs">
                <thead class="bg-slate-50 text-slate-500">
                    <tr>
                        <th class="px-4 py-1.5 text-left font-medium">Kullanıcı</th>
                        <th class="px-4 py-1.5 text-right font-medium">CPU %</th>
                        <th class="px-4 py-1.5 text-right font-medium">RAM (MB)</th>
                        <th class="px-4 py-1.5 text-right font-medium">İşlem Sayısı</th>
                    </tr>
                </thead>
                <tbody class="divide-y divide-slate-50">
                    <tr v-for="u in topUsers" :key="u.user" class="hover:bg-slate-50">
                        <td class="px-4 py-1.5 font-mono text-slate-800">{{ u.user }}</td>
                        <td class="px-4 py-1.5 text-right font-mono">{{ formatNumber(u.cpu_pct, 1) }}</td>
                        <td class="px-4 py-1.5 text-right font-mono">{{ formatNumber(u.mem_mb, 0) }}</td>
                        <td class="px-4 py-1.5 text-right font-mono">{{ u.count }}</td>
                    </tr>
                    <tr v-if="topUsers.length === 0">
                        <td colspan="4" class="px-4 py-3 text-center text-slate-400">Veri yok</td>
                    </tr>
                </tbody>
            </table>
        </div>

        <!-- ── Filter bar ───────────────────────────────────────────────── -->
        <div class="mb-3 rounded-xl border border-slate-200 bg-white p-3 shadow-sm">
            <div class="grid grid-cols-1 gap-3 md:grid-cols-12">
                <div class="md:col-span-3">
                    <label class="block text-[11px] font-medium text-slate-500 mb-1">Kullanıcı</label>
                    <select v-model="filters.user" @change="onFilterChange"
                            class="w-full rounded-lg border border-slate-300 bg-white px-2 py-1.5 text-sm">
                        <option value="">Hepsi</option>
                        <option v-for="u in distinctUsers" :key="u" :value="u">{{ u }}</option>
                    </select>
                </div>
                <div class="md:col-span-2">
                    <label class="block text-[11px] font-medium text-slate-500 mb-1">Min CPU: {{ filters.min_cpu }}%</label>
                    <input v-model.number="filters.min_cpu" @change="onFilterChange"
                           type="range" min="0" max="100" step="1" class="w-full" />
                </div>
                <div class="md:col-span-2">
                    <label class="block text-[11px] font-medium text-slate-500 mb-1">Min RAM: {{ filters.min_mem_mb }} MB</label>
                    <input v-model.number="filters.min_mem_mb" @change="onFilterChange"
                           type="range" min="0" max="2048" step="16" class="w-full" />
                </div>
                <div class="md:col-span-3">
                    <label class="block text-[11px] font-medium text-slate-500 mb-1">Komut Ara</label>
                    <div class="relative">
                        <MagnifyingGlassIcon class="absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400" />
                        <input v-model="filters.search" @keyup.enter="onFilterChange" @change="onFilterChange"
                               type="text" placeholder="httpd, php-fpm..."
                               class="w-full rounded-lg border border-slate-300 bg-white py-1.5 pl-7 pr-2 text-sm" />
                    </div>
                </div>
                <div class="md:col-span-1">
                    <label class="block text-[11px] font-medium text-slate-500 mb-1">Limit</label>
                    <select v-model.number="filters.limit" @change="onFilterChange"
                            class="w-full rounded-lg border border-slate-300 bg-white px-2 py-1.5 text-sm">
                        <option :value="50">50</option>
                        <option :value="100">100</option>
                        <option :value="200">200</option>
                    </select>
                </div>
                <div class="md:col-span-1 flex items-end">
                    <button @click="resetFilters"
                            class="inline-flex w-full items-center justify-center gap-1 rounded-lg border border-slate-300 bg-white px-2 py-1.5 text-xs hover:bg-slate-50">
                        <XMarkIcon class="h-3.5 w-3.5" /> Temizle
                    </button>
                </div>
            </div>
        </div>

        <!-- ── Process table ───────────────────────────────────────────── -->
        <div class="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
            <div class="overflow-x-auto">
                <table class="min-w-full divide-y divide-slate-200 text-xs">
                    <thead class="bg-slate-50">
                        <tr class="text-slate-500">
                            <th class="cursor-pointer px-3 py-2 text-left font-medium hover:bg-slate-100" @click="setSort('pid')">
                                <span class="inline-flex items-center gap-0.5">
                                    PID
                                    <component :is="sortIcon('pid')" v-if="sortIcon('pid')" class="h-3 w-3" />
                                </span>
                            </th>
                            <th class="px-3 py-2 text-left font-medium">Kullanıcı</th>
                            <th class="cursor-pointer px-3 py-2 text-right font-medium hover:bg-slate-100" @click="setSort('cpu')">
                                <span class="inline-flex items-center gap-0.5">
                                    CPU %
                                    <component :is="sortIcon('cpu')" v-if="sortIcon('cpu')" class="h-3 w-3" />
                                </span>
                            </th>
                            <th class="cursor-pointer px-3 py-2 text-right font-medium hover:bg-slate-100" @click="setSort('mem')">
                                <span class="inline-flex items-center gap-0.5">
                                    RAM (MB / %)
                                    <component :is="sortIcon('mem')" v-if="sortIcon('mem')" class="h-3 w-3" />
                                </span>
                            </th>
                            <th class="px-3 py-2 text-right font-medium">VSZ</th>
                            <th class="cursor-pointer px-3 py-2 text-left font-medium hover:bg-slate-100" @click="setSort('runtime')">
                                <span class="inline-flex items-center gap-0.5">
                                    Süre
                                    <component :is="sortIcon('runtime')" v-if="sortIcon('runtime')" class="h-3 w-3" />
                                </span>
                            </th>
                            <th class="px-3 py-2 text-left font-medium">Komut</th>
                            <th class="px-3 py-2 text-center font-medium">Durum</th>
                            <th class="px-3 py-2 text-right font-medium">İşlem</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-slate-100 font-mono">
                        <tr v-for="p in list" :key="p.pid" :class="rowClass(p)">
                            <td class="px-3 py-1.5 text-slate-800">{{ p.pid }}</td>
                            <td class="px-3 py-1.5 text-amber-700">{{ p.user }}</td>
                            <td class="px-3 py-1.5 text-right"
                                :class="(p.cpu_pct ?? p.cpu) > 80 ? 'text-red-700 font-bold' : (p.cpu_pct ?? p.cpu) >= 50 ? 'text-amber-700 font-semibold' : 'text-slate-700'">
                                {{ formatNumber(p.cpu_pct ?? p.cpu, 1) }}
                            </td>
                            <td class="px-3 py-1.5 text-right text-slate-700">
                                {{ formatNumber(p.mem_mb, 0) }} <span class="text-slate-400">/ {{ formatNumber(p.mem_pct ?? p.mem, 1) }}%</span>
                            </td>
                            <td class="px-3 py-1.5 text-right text-slate-500">{{ formatNumber((p.vsz_kb ?? 0) / 1024, 0) }}M</td>
                            <td class="px-3 py-1.5 text-slate-600">{{ p.runtime ?? p.time }}</td>
                            <td class="px-3 py-1.5 text-slate-700" :title="p.args ?? p.cmd">{{ truncate(p.args ?? p.cmd, 80) }}</td>
                            <td class="px-3 py-1.5 text-center">
                                <span class="inline-block rounded bg-slate-100 px-1.5 py-0.5 text-[10px] text-slate-600"
                                      :title="stateLabel(p.stat ?? p.state)">{{ p.stat ?? p.state }}</span>
                            </td>
                            <td class="px-3 py-1.5 text-right">
                                <div class="flex items-center justify-end gap-1">
                                    <span v-if="isProtected(p)"
                                          class="rounded bg-slate-200 px-2 py-0.5 text-[10px] text-slate-500"
                                          title="Korumalı: PID < 100 veya kritik servis">
                                        Korumalı
                                    </span>
                                    <button v-else
                                            @click="openKillModal(p)"
                                            class="rounded bg-red-50 px-2 py-0.5 text-[10px] font-semibold text-red-700 hover:bg-red-100">
                                        Kill
                                    </button>
                                </div>
                            </td>
                        </tr>
                        <tr v-if="list.length === 0">
                            <td colspan="9" class="px-3 py-6 text-center text-slate-400">Filtreyle eşleşen işlem yok.</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <p class="mt-3 text-[11px] text-slate-500">
            Kaynak: sysapi <code class="font-mono">process-list</code> (ps aux + /proc/loadavg) · 5sn cache · Korumalı (PID&lt;100 veya systemd/sshd/httpd/php-fpm) kill edilemez.
        </p>

        <!-- ── Kill confirmation modal ─────────────────────────────────── -->
        <div v-if="killModal.open" class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
            <div class="w-full max-w-lg rounded-xl bg-white shadow-xl">
                <div class="flex items-start gap-3 border-b border-slate-200 px-5 py-4">
                    <ExclamationTriangleIcon class="h-6 w-6 flex-shrink-0 text-red-500" />
                    <div class="flex-1">
                        <h3 class="text-base font-semibold text-slate-900">İşlemi Sonlandır</h3>
                        <p class="mt-0.5 text-xs text-slate-500">
                            PID {{ killModal.process?.pid }} ({{ killModal.process?.user }})
                            kill edilecek. Bu işlem audit log'a kaydedilir.
                        </p>
                    </div>
                    <button @click="closeKillModal" class="text-slate-400 hover:text-slate-600">
                        <XMarkIcon class="h-5 w-5" />
                    </button>
                </div>
                <div class="px-5 py-4">
                    <dl class="grid grid-cols-3 gap-x-3 gap-y-2 rounded-lg border border-slate-200 bg-slate-50 p-3 text-xs">
                        <dt class="text-slate-500">PID</dt>
                        <dd class="col-span-2 font-mono text-slate-800">{{ killModal.process?.pid }}</dd>
                        <dt class="text-slate-500">Kullanıcı</dt>
                        <dd class="col-span-2 font-mono text-slate-800">{{ killModal.process?.user }}</dd>
                        <dt class="text-slate-500">CPU / RAM</dt>
                        <dd class="col-span-2 font-mono text-slate-800">
                            {{ formatNumber(killModal.process?.cpu_pct ?? killModal.process?.cpu, 1) }}%
                            / {{ formatNumber(killModal.process?.mem_mb, 0) }} MB
                        </dd>
                        <dt class="text-slate-500">Süre</dt>
                        <dd class="col-span-2 font-mono text-slate-800">{{ killModal.process?.runtime ?? killModal.process?.time }}</dd>
                        <dt class="text-slate-500">Komut</dt>
                        <dd class="col-span-2 break-all font-mono text-slate-800">{{ killModal.process?.args ?? killModal.process?.cmd }}</dd>
                    </dl>

                    <div class="mt-4 space-y-3">
                        <label class="flex items-start gap-2 text-sm">
                            <input v-model="killModal.force" type="checkbox" class="mt-0.5 rounded border-slate-300" />
                            <span>
                                <span class="font-medium text-slate-800">Force kill (SIGKILL / 9)</span>
                                <span class="block text-[11px] text-slate-500">
                                    Aksi halde SIGTERM (15) gönderilir — işleme temiz kapanma şansı verilir.
                                </span>
                            </span>
                        </label>

                        <div>
                            <label class="block text-xs font-medium text-slate-700 mb-1">Gerekçe (audit log için)</label>
                            <textarea v-model="killModal.reason" rows="2" maxlength="255"
                                      placeholder="Örn: zombie horizon worker, müşteri talebi #12345"
                                      class="w-full rounded-lg border border-slate-300 px-2 py-1.5 text-sm" />
                        </div>
                    </div>
                </div>
                <div class="flex items-center justify-end gap-2 border-t border-slate-200 bg-slate-50 px-5 py-3">
                    <button @click="closeKillModal"
                            class="rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-sm hover:bg-slate-100">
                        İptal
                    </button>
                    <button @click="confirmKill"
                            :disabled="killModal.submitting"
                            :class="killModal.force
                                ? 'bg-red-600 hover:bg-red-700'
                                : 'bg-amber-600 hover:bg-amber-700'"
                            class="rounded-lg px-3 py-1.5 text-sm font-semibold text-white disabled:opacity-50">
                        {{ killModal.force ? 'SIGKILL Gönder (9)' : 'SIGTERM Gönder (15)' }}
                    </button>
                </div>
            </div>
        </div>
    </AdminLayout>
</template>
