<?php
// api/verifikasi.php
// Fitur 2: Keterbaruan Data & Verifikasi Berkala
// Method: GET (list warga perlu update), POST (catat verifikasi), GET?action=config, PUT (update config)

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }

require_once '../config/db.php';
require_once 'middleware.php';

/* ─────────────────────────────────────────────
   HELPER
───────────────────────────────────────────── */
function getKonfig(PDO $pdo, string $kunci, $default = null) {
    $stmt = $pdo->prepare("SELECT nilai, tipe FROM konfigurasi_sistem WHERE kunci = ?");
    $stmt->execute([$kunci]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$row) return $default;
    return match($row['tipe']) {
        'integer' => (int)$row['nilai'],
        'decimal' => (float)$row['nilai'],
        'boolean' => filter_var($row['nilai'], FILTER_VALIDATE_BOOLEAN),
        default   => $row['nilai'],
    };
}

/* ─────────────────────────────────────────────
   CORE: Hitung skor kepercayaan data
   Formula: mulai 100, kurangi seiring waktu
   Decay rate: linear -100/interval_bulan per bulan
───────────────────────────────────────────── */
function hitungSkorKepercayaan(
    ?string $tanggalVerifikasi,
    int $intervalBulan,
    int $minSkor = 40
): array {
    if (!$tanggalVerifikasi) {
        return ['skor' => 0, 'hari_sejak' => null, 'status' => 'kadaluarsa'];
    }

    $tglVerif    = new DateTime($tanggalVerifikasi);
    $today       = new DateTime();
    
    // Jika tanggal verifikasi di masa depan (karena beda timezone / lag server), anggap 0 hari
    if ($tglVerif > $today) {
        $hariSejak = 0;
    } else {
        $diff      = $today->diff($tglVerif);
        $hariSejak = $diff->days;
    }
    $intervalHari = $intervalBulan * 30;

    // Skor linear: 100 di hari 0, turun ke 0 di hari intervalHari
    $skor = max(0, (int)round(100 - ($hariSejak / $intervalHari * 100)));

    $status = match(true) {
        $skor >= 80               => 'terverifikasi',
        $skor >= $minSkor         => 'perlu_update',
        default                   => 'kadaluarsa',
    };

    // Berapa hari lagi sampai perlu_update dan kadaluarsa
    $hariMenujuPerluUpdate  = max(0, (int)($intervalHari * 0.2) - $hariSejak);
    $hariMenujuKadaluarsa   = max(0, (int)($intervalHari * ((100 - $minSkor) / 100)) - $hariSejak);

    return [
        'skor'                    => $skor,
        'hari_sejak_verifikasi'   => $hariSejak,
        'interval_hari'           => $intervalHari,
        'status'                  => $status,
        'hari_menuju_perlu_update' => $hariMenujuPerluUpdate,
        'hari_menuju_kadaluarsa'  => $hariMenujuKadaluarsa,
        'tanggal_kadaluarsa'      => (clone $tglVerif)->modify("+{$intervalHari} days")->format('Y-m-d'),
    ];
}

/* ─────────────────────────────────────────────
   UPDATE skor semua warga secara batch
   Formula: mulai 100, kurangi seiring waktu
───────────────────────────────────────────── */
function updateSkopBatch(PDO $pdo): int {
    $interval = getKonfig($pdo, 'interval_verifikasi_bulan', 6);
    $minSkor  = getKonfig($pdo, 'skor_data_kadaluarsa', 40);

    $wargaList = $pdo->query("SELECT id, tanggal_verifikasi FROM rumah_warga")->fetchAll(PDO::FETCH_ASSOC);
    $updated   = 0;

    $stmt = $pdo->prepare("
        UPDATE rumah_warga SET skor_kepercayaan = ?, status_verifikasi = ? WHERE id = ?
    ");

    foreach ($wargaList as $w) {
        $calc = hitungSkorKepercayaan($w['tanggal_verifikasi'], $interval, $minSkor);
        $stmt->execute([$calc['skor'], $calc['status'], (int)$w['id']]);
        $updated++;
    }

    return $updated;
}

/* ─────────────────────────────────────────────
   ROUTING
───────────────────────────────────────────── */
try {
    $method = $_SERVER['REQUEST_METHOD'];
    $action = $_GET['action'] ?? 'list';

    if ($method === 'GET') {
        // Hanya Admin dan Petugas Lapangan yang boleh melihat data verifikasi
        requireAuth(['admin', 'petugas']);

        if ($action === 'list') {
            // Daftar warga yang perlu diverifikasi
            $statusFilter = $_GET['status'] ?? null; // terverifikasi|perlu_update|kadaluarsa
            $limit        = (int)($_GET['limit'] ?? 50);
            $offset       = (int)($_GET['offset'] ?? 0);

            // Update skor dulu secara batch
            updateSkopBatch($pdo);

            if ($statusFilter === 'semua') {
                $where = "";
            } elseif ($statusFilter === 'terverifikasi' || $statusFilter === 'perlu_update' || $statusFilter === 'kadaluarsa') {
                $where = "WHERE rw.status_verifikasi = " . $pdo->quote($statusFilter);
            } else {
                // Default: Hanya warga yang perlu verifikasi (perlu_update atau kadaluarsa)
                $where = "WHERE rw.status_verifikasi IN ('perlu_update', 'kadaluarsa')";
            }
            $sql   = "
                SELECT rw.id, rw.nama_kepala_keluarga, rw.no_kk,
                       rw.kelurahan, rw.kecamatan,
                       rw.tanggal_verifikasi, rw.petugas_verifikasi,
                       rw.skor_kepercayaan, rw.status_verifikasi,
                       rw.kategori_kemiskinan, rw.status_bantuan,
                       rw.latitude, rw.longitude
                FROM rumah_warga rw
                $where
                ORDER BY rw.skor_kepercayaan ASC, rw.tanggal_verifikasi ASC
                LIMIT $limit OFFSET $offset
            ";
            $rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);

            // Enrichment: hitung detail decay per row
            $interval = getKonfig($pdo, 'interval_verifikasi_bulan', 6);
            $minSkor  = getKonfig($pdo, 'skor_data_kadaluarsa', 40);
            foreach ($rows as &$r) {
                $r['detail_skor'] = hitungSkorKepercayaan(
                    $r['tanggal_verifikasi'], $interval, $minSkor
                );
            }

            // Summary count
            $summary = $pdo->query("
                SELECT status_verifikasi, COUNT(*) as jumlah
                FROM rumah_warga
                GROUP BY status_verifikasi
            ")->fetchAll(PDO::FETCH_KEY_PAIR);

            echo json_encode([
                'success' => true,
                'data'    => $rows,
                'summary' => $summary,
                'total'   => count($rows),
            ]);

        } elseif ($action === 'config') {
            // Ambil semua konfigurasi
            $rows = $pdo->query("SELECT * FROM konfigurasi_sistem ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
            echo json_encode(['success' => true, 'data' => $rows]);

        } elseif ($action === 'riwayat') {
            // Riwayat verifikasi untuk 1 warga
            $wargaId = (int)($_GET['warga_id'] ?? 0);
            $rows    = $pdo->prepare("
                SELECT * FROM riwayat_verifikasi
                WHERE rumah_warga_id = ?
                ORDER BY tanggal DESC LIMIT 20
            ");
            $rows->execute([$wargaId]);
            echo json_encode(['success' => true, 'data' => $rows->fetchAll(PDO::FETCH_ASSOC)]);

        } elseif ($action === 'statistik') {
            updateSkopBatch($pdo);
            $data = [
                'per_status'    => $pdo->query("
                    SELECT status_verifikasi, COUNT(*) as jumlah,
                           ROUND(AVG(skor_kepercayaan)) as avg_skor
                    FROM rumah_warga GROUP BY status_verifikasi
                ")->fetchAll(PDO::FETCH_ASSOC),
                'avg_skor_global' => (float)$pdo->query("SELECT ROUND(AVG(skor_kepercayaan),1) FROM rumah_warga")->fetchColumn(),
                'paling_lama'     => $pdo->query("
                    SELECT nama_kepala_keluarga, tanggal_verifikasi, skor_kepercayaan
                    FROM rumah_warga ORDER BY skor_kepercayaan ASC LIMIT 5
                ")->fetchAll(PDO::FETCH_ASSOC),
            ];
            echo json_encode(['success' => true, 'data' => $data]);
        }

    } elseif ($method === 'POST') {
        // Catat verifikasi baru untuk 1 warga
        // Hanya Admin, Petugas Lapangan, dan Koordinator
        $currentUser = requireAuth(['admin', 'petugas', 'koordinator']);

        $body    = json_decode(file_get_contents('php://input'), true);
        $wargaId = (int)($body['warga_id'] ?? 0);
        $petugas = trim($body['petugas'] ?? '');
        $catatan = $body['catatan'] ?? null;
        $tanggal = $body['tanggal'] ?? date('Y-m-d');

        if (!$wargaId) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'warga_id wajib diisi']);
            exit;
        }

        // Jika koordinator, lakukan pengecekan wilayah
        if ($currentUser['role'] === 'koordinator') {
            $koorIbadahId = (int)$currentUser['rumah_ibadah_id'];
            $wilayahRes = $pdo->prepare("SELECT kelurahan, kecamatan FROM rumah_ibadah WHERE id = ?");
            $wilayahRes->execute([$koorIbadahId]);
            if ($wil = $wilayahRes->fetch(PDO::FETCH_ASSOC)) {
                $kel = $wil['kelurahan'];
                $kec = $wil['kecamatan'];
                
                $wargaRes = $pdo->prepare("SELECT kelurahan, kecamatan FROM rumah_warga WHERE id = ?");
                $wargaRes->execute([$wargaId]);
                if ($wargaRow = $wargaRes->fetch(PDO::FETCH_ASSOC)) {
                    $wKel = strtolower(trim($wargaRow['kelurahan'] ?? ''));
                    $wKec = strtolower(trim($wargaRow['kecamatan'] ?? ''));
                    if (strpos($wKel, strtolower($kel)) === false && strpos($wKec, strtolower($kec)) === false) {
                        http_response_code(403);
                        echo json_encode(['success' => false, 'message' => 'Forbidden: Warga di luar wilayah tugas Anda.']);
                        exit;
                    }
                } else {
                    http_response_code(404);
                    echo json_encode(['success' => false, 'message' => 'Warga tidak ditemukan.']);
                    exit;
                }
            } else {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Forbidden: Wilayah tugas tidak terkonfigurasi.']);
                exit;
            }
        }

        // Ambil skor lama
        $oldRow  = $pdo->prepare("SELECT skor_kepercayaan, status_verifikasi FROM rumah_warga WHERE id = ?");
        $oldRow->execute([$wargaId]);
        $old     = $oldRow->fetch(PDO::FETCH_ASSOC);
        $skorLama = $old ? (int)$old['skor_kepercayaan'] : null;

        // Reset skor ke 100 & update tanggal verifikasi
        $stmt = $pdo->prepare("
            UPDATE rumah_warga
            SET tanggal_verifikasi  = ?,
                petugas_verifikasi  = ?,
                skor_kepercayaan    = 100,
                status_verifikasi   = 'terverifikasi',
                updated_at          = NOW()
            WHERE id = ?
        ");
        $stmt->execute([$tanggal, $petugas ?: null, $wargaId]);

        // Simpan riwayat
        $riwayat = $pdo->prepare("
            INSERT INTO riwayat_verifikasi
              (rumah_warga_id, tanggal, petugas, skor_sebelum, skor_sesudah, catatan)
            VALUES (?, ?, ?, ?, 100, ?)
        ");
        $riwayat->execute([$wargaId, $tanggal, $petugas ?: null, $skorLama, $catatan]);

        echo json_encode([
            'success' => true,
            'message' => 'Verifikasi berhasil dicatat. Skor kepercayaan data dikembalikan ke 100.',
            'skor_lama'  => $skorLama,
            'skor_baru'  => 100,
        ]);

    } elseif ($method === 'PUT') {
        // Update konfigurasi sistem
        // HANYA Admin yang boleh merubah konfigurasi sistem
        requireAuth(['admin']);

        $body = json_decode(file_get_contents('php://input'), true);
        if (!is_array($body)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'Body tidak valid']);
            exit;
        }

        $stmt    = $pdo->prepare("UPDATE konfigurasi_sistem SET nilai = ? WHERE kunci = ?");
        $updated = 0;
        foreach ($body as $kunci => $nilai) {
            $stmt->execute([(string)$nilai, $kunci]);
            $updated += $stmt->rowCount();
        }

        // Setelah konfigurasi diupdate, recalculate semua skor
        updateSkopBatch($pdo);

        echo json_encode([
            'success' => true,
            'message' => "$updated konfigurasi berhasil diperbarui. Skor kepercayaan seluruh data telah dihitung ulang.",
        ]);
    }

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}