<script setup>
import { ref, computed } from 'vue'
import { Head, router, useForm } from '@inertiajs/vue3'
import AdminLayout from '@/Layouts/AdminLayout.vue'
import {
    CircleStackIcon,
    InformationCircleIcon,
    ExclamationTriangleIcon,
    CheckCircleIcon,
    BoltIcon,
    ClockIcon,
    ShieldCheckIcon,
    ArrowPathIcon,
    XCircleIcon,
} from '@heroicons/vue/24/outline'
import { useConfirm } from '@/composables/useConfirm'

const { ask } = useConfirm()

const props = defineProps({
    current: Object,           // {engine, version, label}
    targets: Array,            // [{engine, version, label, note, eol}]
    targets_source: String,    // 'live' | 'cache' | 'hardcoded'
    targets_fetched_at: String, // ISO 8601 timestamp
    stats: Object,             // {database_count, total_size_mb, threads_connected}
    last_preflight: Object,    // null or {target_engine, target_version, backup_path, ...}
    last_dryrun: Object,       // null or {schema_diff_count, data_checksum_mismatches, ...}
    history: { type: Array, default: () => [] },          // Phase 2 — son 10 upgrade/rollback
    rollback_candidate: { type: Object, default: null },  // Phase 2 — en son completed upgrade
})

const showHistory = ref(false)
const rolling = ref(false)

const submitRollback = async () => {
    if (!props.rollback_candidate) return

    const candidate = props.rollback_candidate
    const expected = `ROLLBACK-${candidate.id}`
    const entered = prompt(
        `DİKKAT: Bu işlem DB'yi ${candidate.from} sürümüne geri döndürür.\n\n`
        + `Backup: ${candidate.backup_path}\n`
        + `Backup boyutu: ${candidate.backup_size_mb} MB\n`
        + `Tahmini downtime: 2-10 dk\n\n`
        + `Devam için onay kodunu birebir gir:\n\n${expected}`,
    )
    if (entered !== expected) {
        alert('Onay kodu eşleşmedi, işlem iptal.')
        return
    }

    const ok = await ask({
        title: 'ROLLBACK SON ONAY',
        message: `${candidate.to} → ${candidate.from} sürümüne dönülecek. Backup'tan import yapılacak. Devam ediyor musun?`,
        variant: 'danger',
        confirmText: 'Rollback Başlat',
        cancelText: 'İptal',
    })
    if (!ok) return

    rolling.value = true
    router.post(
        route('admin.db-version.rollback'),
        { history_id: candidate.id, confirm_token: entered },
        {
            preserveScroll: true,
            onFinish: () => { rolling.value = false },
        }
    )
}

const historyStatusBadge = (s) => ({
    running: 'bg-blue-100 text-blue-700',
    completed: 'bg-emerald-100 text-emerald-700',
    failed: 'bg-red-100 text-red-700',
    rolled_back: 'bg-amber-100 text-amber-700',
}[s] || 'bg-slate-100 text-slate-600')

const historyActionBadge = (a) => a === 'rollback'
    ? 'bg-amber-100 text-amber-700'
    : 'bg-indigo-100 text-indigo-700'

const dryrun = computed(() => props.last_dryrun)
const applyingFixes = ref(false)
const dryRunning = ref(false)

// Auto-fix counts (across all DBs)
const totalAutoFixable = computed(() => {
    if (!preflight.value?.compat_issues) return 0
    let n = 0
    for (const dbName in preflight.value.compat_issues) {
        const dbScan = preflight.value.compat_issues[dbName]
        for (const issue of dbScan.issues || []) {
            if (issue.auto_fix?.sql && issue.fix_status !== 'applied') n++
        }
    }
    return n
})

const totalAutoFixableSafe = computed(() => {
    if (!preflight.value?.compat_issues) return 0
    let n = 0
    for (const dbName in preflight.value.compat_issues) {
        const dbScan = preflight.value.compat_issues[dbName]
        for (const issue of dbScan.issues || []) {
            if (issue.auto_fix?.sql && !issue.auto_fix.irreversible && issue.fix_status !== 'applied') n++
        }
    }
    return n
})

const applyAllAutoFixes = async (irreversibleOk) => {
    const msg = irreversibleOk
        ? `Geri alınamaz değişiklikler dahil ${totalAutoFixable.value} otomatik düzeltme uygulanacak. Backup'ın hazır olduğundan emin misin?`
        : `${totalAutoFixableSafe.value} güvenli (geri alınabilir) otomatik düzeltme uygulanacak. Devam edilsin mi?`
    const ok = await ask({
        title: irreversibleOk ? 'Tüm Düzeltmeleri Uygula' : 'Güvenli Düzeltmeleri Uygula',
        message: msg,
        variant: irreversibleOk ? 'danger' : 'warning',
        confirmText: 'Uygula',
        cancelText: 'İptal',
    })
    if (!ok) return

    applyingFixes.value = true
    router.post(route('admin.db-version.apply-auto-fixes'), { irreversible_ok: irreversibleOk }, {
        preserveScroll: true,
        onFinish: () => { applyingFixes.value = false },
    })
}

const applyOneFix = async (dbName, type, irreversible) => {
    const msg = irreversible
        ? `Bu düzeltme GERİ ALINAMAZ. ${dbName}/${type} için uygulansın mı?`
        : `${dbName}/${type} için otomatik düzeltme uygulansın mı?`
    const ok = await ask({
        title: 'Otomatik Düzelt',
        message: msg,
        variant: irreversible ? 'danger' : 'warning',
        confirmText: 'Uygula',
        cancelText: 'İptal',
    })
    if (!ok) return

    applyingFixes.value = true
    router.post(route('admin.db-version.apply-auto-fixes'), {
        db_name: dbName,
        types: [type],
        irreversible_ok: irreversible,
    }, {
        preserveScroll: true,
        onFinish: () => { applyingFixes.value = false },
    })
}

const runDryRun = async () => {
    if (!selectedTarget.value) {
        alert('Önce hedef sürümü seç.')
        return
    }
    const ok = await ask({
        title: 'Dry-Run Test Ortamı',
        message: `Backup'tan paralel DB instance kurulacak (port 3399). ~5-15dk sürebilir. Production DB'ye dokunulmaz.\n\nHedef: ${selectedTarget.value.label}`,
        variant: 'info',
        confirmText: 'Başlat',
        cancelText: 'İptal',
    })
    if (!ok) return

    dryRunning.value = true
    router.post(route('admin.db-version.dry-run'), {
        target_engine: selectedTarget.value.engine,
        target_version: selectedTarget.value.version,
    }, {
        preserveScroll: true,
        onFinish: () => { dryRunning.value = false },
    })
}

const refreshing = ref(false)
const refreshVersions = () => {
    refreshing.value = true
    router.post(route('admin.db-version.refresh-versions'), {}, {
        preserveScroll: true,
        onFinish: () => { refreshing.value = false },
    })
}

const sourceBadge = computed(() => {
    const s = props.targets_source || 'hardcoded'
    return {
        live: { color: 'bg-emerald-100 text-emerald-700', label: 'Canlı repo' },
        cache: { color: 'bg-blue-100 text-blue-700', label: 'Cache (24h)' },
        hardcoded: { color: 'bg-amber-100 text-amber-700', label: 'Sabit liste — sysapi yok' },
    }[s] || { color: 'bg-slate-100 text-slate-700', label: s }
})

const fetchedAge = computed(() => {
    if (!props.targets_fetched_at) return ''
    const diff = Date.now() - new Date(props.targets_fetched_at).getTime()
    const hrs = Math.floor(diff / 3600000)
    if (hrs < 1) return 'şimdi'
    if (hrs < 24) return `${hrs}sa önce`
    return `${Math.floor(hrs / 24)}g önce`
})

const eolWarning = (eol) => {
    if (!eol) return null
    const eolDate = new Date(eol + '-01')
    const monthsLeft = (eolDate - new Date()) / (1000 * 60 * 60 * 24 * 30)
    if (monthsLeft < 0) return { class: 'text-red-700', text: 'EOL geçti' }
    if (monthsLeft < 12) return { class: 'text-amber-700', text: `${Math.floor(monthsLeft)}ay kaldı` }
    return null
}

// ── Target selection ───────────────────────────────────────────────────────
const selectedKey = ref('')

const selectedTarget = computed(() => {
    if (!selectedKey.value) return null
    const [engine, version] = selectedKey.value.split('|')
    return props.targets.find((t) => t.engine === engine && t.version === version)
})

const isSelectedSameAsCurrent = computed(() => {
    if (!selectedTarget.value) return false
    return selectedTarget.value.engine === props.current.engine
        && selectedTarget.value.version.split('.').slice(0, 2).join('.') ===
           props.current.version.split('.').slice(0, 2).join('.')
})

// ── Preflight ──────────────────────────────────────────────────────────────
const prepareForm = useForm({ target_engine: '', target_version: '' })

const submitPrepare = async () => {
    if (!selectedTarget.value) {
        alert('Önce hedef versiyon seç.')
        return
    }
    const ok = await ask({
        title: 'Preflight Onayı',
        message: `Tam mysqldump backup alınacak ve uyumluluk taraması yapılacak. Bu işlem 5-30dk sürebilir.\n\nHedef: ${selectedTarget.value.label}`,
        variant: 'warning',
        confirmText: 'Başlat',
        cancelText: 'İptal',
    })
    if (!ok) return

    prepareForm.target_engine = selectedTarget.value.engine
    prepareForm.target_version = selectedTarget.value.version
    prepareForm.post(route('admin.db-version.prepare'), { preserveScroll: true })
}

// ── Switch ─────────────────────────────────────────────────────────────────
const switchForm = useForm({
    target_engine: '',
    target_version: '',
    confirm_token: '',
})

const preflight = computed(() => props.last_preflight)
const preflightMatch = computed(() => {
    if (!preflight.value || !selectedTarget.value) return false
    return preflight.value.target_engine === selectedTarget.value.engine
        && preflight.value.target_version === selectedTarget.value.version
})

const goNoGoBadge = computed(() => ({
    go: 'bg-emerald-100 text-emerald-700',
    warn: 'bg-amber-100 text-amber-700',
    'no-go': 'bg-red-100 text-red-700',
}[preflight.value?.go_no_go] || 'bg-slate-100 text-slate-600'))

const submitSwitch = async () => {
    if (!preflightMatch.value) {
        alert('Preflight ile hedef uyumsuz. Önce preflight çalıştır.')
        return
    }

    const expected = `MIGRATE-${selectedTarget.value.engine.toUpperCase()}-${selectedTarget.value.version.replace('.', '')}`
    const entered = prompt(
        `DİKKAT: Bu işlem ~${preflight.value.estimated_downtime_min}dk downtime yaratır.\n\n`
        + `Devam için aşağıdaki onay kodunu birebir gir:\n\n${expected}`,
    )
    if (entered !== expected) {
        alert('Onay kodu eşleşmedi, işlem iptal.')
        return
    }

    const ok = await ask({
        title: 'SON ONAY',
        message: `Hedef: ${selectedTarget.value.label}\nDowntime: ~${preflight.value.estimated_downtime_min} dk\nBackup: ${preflight.value.backup_path}\n\nDevam ediyor musun?`,
        variant: 'danger',
        confirmText: 'Upgrade Başlat',
        cancelText: 'İptal',
    })
    if (!ok) return

    switchForm.target_engine = selectedTarget.value.engine
    switchForm.target_version = selectedTarget.value.version
    switchForm.confirm_token = entered
    switchForm.post(route('admin.db-version.switch'), { preserveScroll: true })
}

const formatMb = (mb) => {
    if (mb >= 1024) return (mb / 1024).toFixed(1) + ' GB'
    return mb + ' MB'
}
</script>

<template>
    <Head title="MySQL Sürüm Yükseltici" />
    <AdminLayout>
        <template #header>MySQL / MariaDB Sürüm Yükseltici</template>

        <div class="mb-4 rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-900">
            <div class="flex gap-3">
                <ExclamationTriangleIcon class="h-5 w-5 flex-shrink-0 text-red-600" />
                <div class="space-y-2">
                    <div>
                        <strong>DİKKAT: Hiçbir engine geçişi %100 uyumlu değildir.</strong>
                        MariaDB ↔ MySQL arasında JSON, SEQUENCES, auth_plugin, CHECK constraint,
                        ROW_FORMAT, GTID, encryption (TDE) gibi alanlarda davranış farkları vardır.
                        Preflight uyumluluk taraması temel sorunları yakalar ama <strong>her şeyi yakalamaz</strong>.
                    </div>
                    <div>
                        Mutlaka iki adımlı akışı takip et: <strong>1)</strong> Preflight (full mysqldump backup + uyumluluk taraması)
                        → <strong>2)</strong> Switch (binary install + mysql_upgrade).
                        Üretimde maintenance mode aç, ~5-30dk downtime planla, <strong>backup'tan geri dönüş planını test et</strong>.
                    </div>
                </div>
            </div>
        </div>

        <!-- Current snapshot -->
        <div class="mb-6 grid grid-cols-1 md:grid-cols-4 gap-3">
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-xs text-slate-500">
                    <CircleStackIcon class="h-4 w-4" /> Mevcut Sürüm
                </div>
                <div class="mt-2 text-xl font-bold">{{ current.label }}</div>
                <div class="text-xs text-slate-500 mt-1">Engine: {{ current.engine }}</div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-xs text-slate-500">
                    <CircleStackIcon class="h-4 w-4" /> Veritabanları
                </div>
                <div class="mt-2 text-xl font-bold">{{ stats.database_count }}</div>
                <div class="text-xs text-slate-500 mt-1">toplam DB</div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-xs text-slate-500">
                    <ArrowPathIcon class="h-4 w-4" /> Boyut
                </div>
                <div class="mt-2 text-xl font-bold">{{ formatMb(stats.total_size_mb) }}</div>
                <div class="text-xs text-slate-500 mt-1">disk üzerinde</div>
            </div>
            <div class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
                <div class="flex items-center gap-2 text-xs text-slate-500">
                    <BoltIcon class="h-4 w-4" /> Aktif Bağlantı
                </div>
                <div class="mt-2 text-xl font-bold">{{ stats.threads_connected }}</div>
                <div class="text-xs text-slate-500 mt-1">canlı thread</div>
            </div>
        </div>

        <!-- Target selection -->
        <div class="mb-6 rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
            <div class="flex flex-wrap items-center justify-between gap-2 mb-3">
                <h3 class="text-sm font-semibold flex items-center gap-2">
                    <BoltIcon class="h-4 w-4 text-indigo-500" />
                    Hedef Sürüm Seç
                    <span :class="['rounded px-2 py-0.5 text-[10px] font-bold', sourceBadge.color]">
                        {{ sourceBadge.label }}
                    </span>
                    <span v-if="fetchedAge" class="text-[10px] font-normal text-slate-400">
                        ({{ fetchedAge }})
                    </span>
                </h3>
                <button
                    @click="refreshVersions"
                    :disabled="refreshing"
                    class="inline-flex items-center gap-1 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-50 disabled:opacity-50"
                    title="Repo'lardan yeni MariaDB/MySQL versiyonlarını çek"
                >
                    <ArrowPathIcon class="h-3.5 w-3.5" :class="refreshing ? 'animate-spin' : ''" />
                    {{ refreshing ? 'Yenileniyor…' : 'Versiyonları Yenile' }}
                </button>
            </div>

            <div v-if="targets_source === 'hardcoded'"
                 class="mb-3 rounded-lg bg-amber-50 border border-amber-200 p-2 text-xs text-amber-900">
                <strong>Sysapi script kurulu değil</strong> — sabit liste gösteriliyor.
                Sunucuya <code class="font-mono bg-amber-100 px-1">onx-db-versions-available</code>
                deploy edilince repo'lardan canlı versiyon çekilir.
            </div>

            <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
                <label v-for="t in targets" :key="`${t.engine}|${t.version}`"
                       class="cursor-pointer rounded-xl border p-3"
                       :class="selectedKey === `${t.engine}|${t.version}` ? 'border-indigo-500 bg-indigo-50 ring-2 ring-indigo-100' : 'border-slate-200 bg-white hover:border-slate-300'">
                    <input type="radio" v-model="selectedKey" :value="`${t.engine}|${t.version}`" class="sr-only" />
                    <div class="flex items-center justify-between">
                        <div class="font-semibold text-sm">{{ t.label }}</div>
                        <span :class="['text-[10px] font-mono uppercase rounded px-1.5 py-0.5',
                            t.engine === 'mariadb' ? 'bg-amber-100 text-amber-700' : 'bg-blue-100 text-blue-700']">
                            {{ t.engine }}
                        </span>
                    </div>
                    <p class="text-xs text-slate-500 mt-1">{{ t.note }}</p>
                    <p v-if="eolWarning(t.eol)" class="text-xs mt-1 font-semibold" :class="eolWarning(t.eol).class">
                        ⚠ {{ eolWarning(t.eol).text }}
                    </p>
                </label>
            </div>

            <div v-if="isSelectedSameAsCurrent" class="mt-3 rounded-lg bg-amber-50 border border-amber-200 p-3 text-xs text-amber-900">
                Seçili sürüm mevcut sürümle aynı majör.minör. Yükseltme yapmıyorsun.
            </div>

            <div class="mt-4 flex items-center justify-end gap-2">
                <button @click="submitPrepare"
                        :disabled="!selectedTarget || prepareForm.processing || isSelectedSameAsCurrent"
                        class="inline-flex items-center gap-1 rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-700 disabled:opacity-50">
                    <ShieldCheckIcon class="h-4 w-4" />
                    {{ prepareForm.processing ? 'Preflight çalışıyor…' : '1. Preflight Başlat' }}
                </button>
            </div>
        </div>

        <!-- Preflight result -->
        <div v-if="preflight" class="mb-6 rounded-xl border-2 p-5 shadow-sm"
             :class="preflightMatch ? 'border-emerald-300 bg-emerald-50/30' : 'border-amber-300 bg-amber-50/20'">
            <div class="flex items-start justify-between gap-3 mb-3">
                <h3 class="font-semibold flex items-center gap-2">
                    <ShieldCheckIcon class="h-5 w-5 text-emerald-600" />
                    Preflight Raporu
                </h3>
                <span :class="['rounded-full px-2.5 py-0.5 text-xs font-bold uppercase', goNoGoBadge]">
                    {{ preflight.go_no_go }}
                </span>
            </div>

            <div class="grid grid-cols-2 sm:grid-cols-4 gap-3 text-sm">
                <div>
                    <div class="text-xs text-slate-500">Hedef</div>
                    <div class="font-semibold">{{ preflight.target_engine }} {{ preflight.target_version }}</div>
                </div>
                <div>
                    <div class="text-xs text-slate-500">Backup</div>
                    <div class="font-semibold">{{ formatMb(preflight.backup_size_mb) }}</div>
                </div>
                <div>
                    <div class="text-xs text-slate-500">Aktif bağlantı</div>
                    <div class="font-semibold">{{ preflight.connections_active }}</div>
                </div>
                <div>
                    <div class="text-xs text-slate-500">Tahmini downtime</div>
                    <div class="font-semibold flex items-center gap-1">
                        <ClockIcon class="h-3.5 w-3.5" />
                        ~{{ preflight.estimated_downtime_min }} dk
                    </div>
                </div>
            </div>

            <div class="mt-3 font-mono text-[11px] text-slate-500 truncate">
                Backup yolu: {{ preflight.backup_path }}
            </div>

            <div v-if="preflight.deprecated_features?.length" class="mt-3 rounded-lg bg-amber-50 border border-amber-200 p-3 text-xs text-amber-900">
                <strong class="block mb-1 flex items-center gap-1">
                    <ExclamationTriangleIcon class="h-4 w-4" />
                    Eski özellik tespitleri ({{ preflight.deprecated_features.length }}):
                </strong>
                <ul class="list-disc list-inside space-y-0.5">
                    <li v-for="(d, i) in preflight.deprecated_features" :key="i" class="font-mono">{{ d }}</li>
                </ul>
            </div>
            <div v-else class="mt-3 rounded-lg bg-emerald-50 border border-emerald-200 p-3 text-xs text-emerald-900 flex items-center gap-2">
                <CheckCircleIcon class="h-4 w-4 flex-shrink-0" />
                Eski özellik tespit edilmedi — temiz upgrade yolu.
            </div>

            <!-- Cross-engine compatibility scan (DB başına) -->
            <div v-if="preflight.compat_issues && Object.keys(preflight.compat_issues).length"
                 class="mt-3 rounded-lg border border-amber-200 bg-amber-50 p-3 text-xs">
                <div class="mb-2 flex items-center justify-between gap-2">
                    <strong class="flex items-center gap-1 text-amber-900">
                        <ExclamationTriangleIcon class="h-4 w-4" />
                        Veritabanı Uyumluluk Sorunları ({{ Object.keys(preflight.compat_issues).length }} DB, {{ totalAutoFixable }} otomatik düzeltilebilir)
                    </strong>
                    <div class="flex gap-1">
                        <button
                            v-if="totalAutoFixable > 0"
                            @click="applyAllAutoFixes(false)"
                            :disabled="applyingFixes"
                            class="rounded bg-emerald-600 px-2.5 py-1 text-[11px] font-semibold text-white hover:bg-emerald-700 disabled:opacity-50"
                            title="Geri alınabilir tüm sorunları otomatik düzelt"
                        >
                            <BoltIcon class="inline h-3 w-3" />
                            Güvenli düzelt ({{ totalAutoFixableSafe }})
                        </button>
                        <button
                            v-if="totalAutoFixable > totalAutoFixableSafe"
                            @click="applyAllAutoFixes(true)"
                            :disabled="applyingFixes"
                            class="rounded bg-amber-600 px-2.5 py-1 text-[11px] font-semibold text-white hover:bg-amber-700 disabled:opacity-50"
                            title="Geri alınamayanlar dahil tümünü uygula"
                        >
                            Hepsini düzelt (geri alınamaz dahil)
                        </button>
                    </div>
                </div>
                <div class="space-y-2">
                    <div v-for="(dbScan, dbName) in preflight.compat_issues" :key="dbName"
                         class="rounded border border-slate-200 bg-white p-2">
                        <div class="flex items-center justify-between gap-2">
                            <span class="font-mono text-xs font-semibold text-slate-800">{{ dbScan.db_name }}</span>
                            <div class="flex items-center gap-1">
                                <span v-if="dbScan.summary" class="text-[10px] text-slate-500">
                                    {{ dbScan.summary.total }} sorun · {{ dbScan.summary.auto_fixable }} otomatik
                                </span>
                                <span :class="[
                                    'rounded px-1.5 py-0.5 text-[10px] font-bold uppercase',
                                    dbScan.severity === 'block' ? 'bg-red-100 text-red-700'
                                    : dbScan.severity === 'warn' ? 'bg-amber-100 text-amber-700'
                                    : 'bg-emerald-100 text-emerald-700'
                                ]">{{ dbScan.severity }}</span>
                            </div>
                        </div>
                        <ul class="mt-1 space-y-1">
                            <li v-for="(issue, i) in dbScan.issues" :key="i" class="text-[11px]">
                                <div class="flex items-start gap-2">
                                    <span :class="[
                                        'flex-shrink-0 rounded px-1 py-0.5 font-mono text-[9px] font-bold uppercase',
                                        issue.severity === 'block' ? 'bg-red-100 text-red-700'
                                        : 'bg-amber-100 text-amber-700'
                                    ]">{{ issue.type }}</span>
                                    <span class="flex-1 text-slate-700">{{ issue.message }}</span>
                                    <span v-if="issue.fix_status === 'applied'"
                                          class="rounded bg-emerald-100 px-1.5 py-0.5 text-[9px] font-bold text-emerald-700">
                                        ✓ DÜZELTİLDİ
                                    </span>
                                    <span v-else-if="issue.fix_status === 'failed'"
                                          class="rounded bg-red-100 px-1.5 py-0.5 text-[9px] font-bold text-red-700"
                                          :title="issue.fix_error">
                                        ✗ HATA
                                    </span>
                                    <button v-else-if="issue.auto_fix"
                                            @click="applyOneFix(dbName, issue.type, issue.auto_fix.irreversible)"
                                            :disabled="applyingFixes"
                                            class="rounded bg-emerald-50 border border-emerald-300 px-1.5 py-0.5 text-[9px] font-semibold text-emerald-700 hover:bg-emerald-100 disabled:opacity-50"
                                            :title="issue.auto_fix.description">
                                        Düzelt
                                    </button>
                                </div>
                                <div v-if="issue.auto_fix" class="ml-12 mt-0.5 font-mono text-[10px] text-slate-400 truncate">
                                    SQL: {{ issue.auto_fix.sql }}
                                </div>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- Dry-run section -->
            <div class="mt-3 rounded-lg border border-indigo-200 bg-indigo-50 p-3 text-xs">
                <div class="flex items-center justify-between gap-2 mb-2">
                    <strong class="flex items-center gap-1 text-indigo-900">
                        <ShieldCheckIcon class="h-4 w-4" />
                        Dry-Run Test Ortamı
                    </strong>
                    <button
                        @click="runDryRun"
                        :disabled="!selectedTarget || dryRunning"
                        class="rounded bg-indigo-600 px-2.5 py-1 text-[11px] font-semibold text-white hover:bg-indigo-700 disabled:opacity-50"
                        title="Backup'tan paralel DB instance kur, hedef sürümde test et"
                    >
                        <ShieldCheckIcon class="inline h-3 w-3" />
                        {{ dryRunning ? 'Dry-run çalışıyor…' : 'Dry-Run Çalıştır' }}
                    </button>
                </div>
                <p class="text-slate-600">
                    Backup'tan paralel bir DB instance (port 3399) kurulur, hedef sürümde restore + mysql_upgrade test edilir.
                    Sonra production ile schema farkı + CHECKSUM TABLE karşılaştırması yapılır. <strong>Production DB'ye dokunulmaz.</strong>
                </p>
                <div v-if="dryrun" class="mt-2 rounded border border-indigo-300 bg-white p-2">
                    <div class="grid grid-cols-2 sm:grid-cols-4 gap-2 text-[11px]">
                        <div>
                            <div class="text-slate-500">Schema farkı</div>
                            <div :class="['font-semibold', dryrun.schema_diff_count === 0 ? 'text-emerald-700' : 'text-amber-700']">
                                {{ dryrun.schema_diff_count }} tablo
                            </div>
                        </div>
                        <div>
                            <div class="text-slate-500">Data checksum mismatch</div>
                            <div :class="['font-semibold', dryrun.data_checksum_mismatches === 0 ? 'text-emerald-700' : 'text-red-700']">
                                {{ dryrun.data_checksum_mismatches }} tablo
                            </div>
                        </div>
                        <div>
                            <div class="text-slate-500">Upgrade warnings</div>
                            <div :class="['font-semibold', (dryrun.upgrade_warnings || 0) === 0 ? 'text-emerald-700' : 'text-amber-700']">
                                {{ dryrun.upgrade_warnings || 0 }}
                            </div>
                        </div>
                        <div>
                            <div class="text-slate-500">Süre</div>
                            <div class="font-semibold">{{ dryrun.duration_seconds }}s</div>
                        </div>
                    </div>
                    <div v-if="dryrun.schema_diffs?.length" class="mt-2">
                        <details>
                            <summary class="cursor-pointer text-[10px] font-semibold text-indigo-700">Schema farkları ({{ dryrun.schema_diffs.length }})</summary>
                            <ul class="mt-1 list-disc list-inside font-mono text-[10px] text-slate-700">
                                <li v-for="(d, i) in dryrun.schema_diffs" :key="i">{{ d }}</li>
                            </ul>
                        </details>
                    </div>
                    <div class="mt-2 text-[10px] text-indigo-700">
                        <strong>Yorum:</strong>
                        <span v-if="dryrun.schema_diff_count === 0 && dryrun.data_checksum_mismatches === 0">
                            Temiz migration profili — production'a geçiş düşük riskli.
                        </span>
                        <span v-else>
                            Production geçişinden önce schema/data farklarını incele, gerekirse auto-fix uygula ve tekrar dry-run çalıştır.
                        </span>
                    </div>
                </div>
            </div>

            <!-- Switch button -->
            <div class="mt-4 flex items-center justify-end gap-2">
                <button v-if="preflightMatch"
                        @click="submitSwitch"
                        :disabled="switchForm.processing"
                        class="inline-flex items-center gap-1 rounded-lg bg-red-600 px-4 py-2 text-sm font-semibold text-white hover:bg-red-700 disabled:opacity-50">
                    <BoltIcon class="h-4 w-4" />
                    {{ switchForm.processing ? 'Migration sürüyor…' : '3. Migration Başlat (DESTRUCTIVE)' }}
                </button>
                <div v-else class="text-xs text-amber-700 flex items-center gap-1">
                    <XCircleIcon class="h-4 w-4" />
                    Preflight ile mevcut seçim uyumsuz — yeniden preflight çalıştır.
                </div>
            </div>
        </div>

        <!-- Manual test checklist -->
        <div class="rounded-xl border border-slate-200 bg-white p-5 mb-6">
            <h3 class="text-sm font-semibold mb-3 flex items-center gap-2">
                <ShieldCheckIcon class="h-4 w-4 text-emerald-500" />
                Migration Sonrası Manuel Test Rehberi
            </h3>
            <p class="text-xs text-slate-500 mb-3">
                Auto-fix + dry-run %100 garanti vermez. Switch sonrası mutlaka şunları manuel test et:
            </p>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-3 text-xs">
                <ul class="space-y-1.5 text-slate-700">
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>SELECT VERSION()</strong> ile yeni sürümü doğrula</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>SHOW PROCESSLIST</strong> aktif bağlantı durumu</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>SHOW WARNINGS</strong> mysql_upgrade çıktısında uyarılar</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>Login testi</strong> tüm DB user'lar bağlanabiliyor mu (özellikle MariaDB→MySQL caching_sha2)</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>WordPress smoke test</strong> en kritik müşteri sitesini tarayıcıdan aç</span>
                    </li>
                </ul>
                <ul class="space-y-1.5 text-slate-700">
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>Stored procedure</strong> CALL test her routine için</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>Trigger test</strong> INSERT/UPDATE/DELETE ile her trigger</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>FULLTEXT sorgu</strong> MATCH(...) AGAINST(...) sonuçları kontrol</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>Backup restore test</strong> yeni sürümden backup alıp eski sürüme restore edilebilir mi (rollback path)</span>
                    </li>
                    <li class="flex items-start gap-2">
                        <CheckCircleIcon class="h-4 w-4 text-slate-300 flex-shrink-0 mt-0.5" />
                        <span><strong>Performance benchmark</strong> kritik sorguları EXPLAIN ile karşılaştır (optimizer farklı planlar üretebilir)</span>
                    </li>
                </ul>
            </div>
        </div>

        <!-- Rollback panel (Phase 2) — son completed upgrade varsa -->
        <div v-if="rollback_candidate" class="mb-4 rounded-xl border-2 border-amber-300 bg-amber-50 p-5 shadow-sm">
            <h3 class="mb-3 flex items-center gap-2 text-base font-semibold text-amber-900">
                <ArrowPathIcon class="h-5 w-5 text-amber-600" />
                Önceki Sürüme Dön (Rollback)
            </h3>
            <p class="mb-3 text-sm text-amber-900">
                En son tamamlanan upgrade <code class="rounded bg-white px-1.5 py-0.5 font-mono">#{{ rollback_candidate.id }}</code>
                tarafından alınan backup ile <strong>{{ rollback_candidate.from }}</strong> sürümüne dönebilirsin.
                Bu işlem yeni sürümde yapılan tüm değişiklikleri (post-upgrade veri) silen geriye dönüştür.
            </p>
            <div class="mb-3 grid grid-cols-2 gap-3 text-xs sm:grid-cols-4">
                <div>
                    <p class="text-amber-700">Mevcut Sürüm</p>
                    <p class="font-mono font-bold">{{ rollback_candidate.to }}</p>
                </div>
                <div>
                    <p class="text-amber-700">Dönülecek</p>
                    <p class="font-mono font-bold">{{ rollback_candidate.from }}</p>
                </div>
                <div>
                    <p class="text-amber-700">Backup</p>
                    <p class="font-mono text-[10px]">{{ rollback_candidate.backup_path }}</p>
                    <p class="text-[10px]">{{ rollback_candidate.backup_size_mb }} MB</p>
                </div>
                <div>
                    <p class="text-amber-700">Upgrade Zamanı</p>
                    <p class="font-mono text-[10px]">{{ rollback_candidate.finished_at }}</p>
                </div>
            </div>
            <button @click="submitRollback" :disabled="rolling"
                    class="inline-flex items-center gap-2 rounded-lg bg-amber-600 px-4 py-2 text-sm font-semibold text-white hover:bg-amber-700 disabled:opacity-50">
                <ArrowPathIcon class="h-4 w-4" :class="rolling ? 'animate-spin' : ''" />
                {{ rolling ? 'Rollback çalışıyor...' : 'Rollback Başlat' }}
            </button>
        </div>

        <!-- Upgrade history (Phase 2) -->
        <div v-if="history.length > 0" class="mb-4 rounded-xl border border-slate-200 bg-white shadow-sm">
            <button @click="showHistory = !showHistory"
                    class="flex w-full items-center justify-between border-b border-slate-100 p-4 text-left hover:bg-slate-50">
                <h3 class="flex items-center gap-2 text-sm font-semibold text-slate-800">
                    <ClockIcon class="h-4 w-4 text-indigo-500" />
                    Sürüm Geçmişi
                    <span class="text-xs font-normal text-slate-500">({{ history.length }} kayıt)</span>
                </h3>
                <span class="text-xs text-slate-500">{{ showHistory ? 'Gizle ▲' : 'Göster ▼' }}</span>
            </button>
            <div v-if="showHistory" class="overflow-x-auto">
                <table class="min-w-full divide-y divide-slate-100 text-sm">
                    <thead class="bg-slate-50 text-xs uppercase text-slate-500">
                        <tr>
                            <th class="px-3 py-2 text-left">#</th>
                            <th class="px-3 py-2 text-left">Tip</th>
                            <th class="px-3 py-2 text-left">From → To</th>
                            <th class="px-3 py-2 text-left">Durum</th>
                            <th class="px-3 py-2 text-right">Downtime</th>
                            <th class="px-3 py-2 text-left">Backup</th>
                            <th class="px-3 py-2 text-left">Zaman</th>
                            <th class="px-3 py-2 text-left">User</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-slate-100">
                        <tr v-for="h in history" :key="h.id" class="hover:bg-slate-50">
                            <td class="px-3 py-2 font-mono text-xs text-slate-500">{{ h.id }}</td>
                            <td class="px-3 py-2">
                                <span :class="['rounded px-2 py-0.5 text-xs font-medium', historyActionBadge(h.action)]">
                                    {{ h.action === 'rollback' ? 'Rollback' : 'Upgrade' }}
                                </span>
                            </td>
                            <td class="px-3 py-2 font-mono text-xs">
                                {{ h.from }} <span class="text-slate-400">→</span> {{ h.to }}
                            </td>
                            <td class="px-3 py-2">
                                <span :class="['rounded px-2 py-0.5 text-xs', historyStatusBadge(h.status)]">
                                    {{ {
                                        running: 'Çalışıyor',
                                        completed: 'Tamamlandı',
                                        failed: 'Hata',
                                        rolled_back: 'Geri Alındı',
                                    }[h.status] || h.status }}
                                </span>
                            </td>
                            <td class="px-3 py-2 text-right font-mono text-xs">{{ h.downtime_seconds }}s</td>
                            <td class="px-3 py-2 font-mono text-[10px] text-slate-600 max-w-[200px] truncate" :title="h.backup_path">
                                {{ h.backup_path ? `${h.backup_size_mb} MB` : '—' }}
                            </td>
                            <td class="px-3 py-2 text-xs text-slate-600">{{ h.started_at }}</td>
                            <td class="px-3 py-2 text-xs text-slate-600">{{ h.initiated_by_name || '—' }}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <!-- Migration steps reference -->
        <div class="rounded-xl border border-slate-200 bg-slate-50 p-5">
            <h3 class="text-sm font-semibold mb-2">Migration Adımları (otomatik)</h3>
            <ol class="text-xs text-slate-600 space-y-1 list-decimal list-inside">
                <li>Tam mysqldump (--all-databases --routines --triggers --events --single-transaction)</li>
                <li>SHA-256 backup integrity check</li>
                <li>21 check uyumluluk taraması + auto-fix uygulaması</li>
                <li>Dry-run paralel instance ile test (opsiyonel ama önerilir)</li>
                <li>Servis durdur (systemctl stop)</li>
                <li>Repo swap (dnf module / apt) + hedef versiyon install</li>
                <li>Servis başlat + 60sn socket bekle</li>
                <li>mysql_upgrade --force (schema sync)</li>
                <li>Verify (SELECT VERSION())</li>
            </ol>
        </div>
    </AdminLayout>
</template>
