<?php

/**
 * Log Sistemi Fonksiyonları
 * Tüm sistem işlemlerini kaydetmek ve geri alma özelliği sağlamak için
 */

/**
 * Sistem logu ekle
 * @param PDO $db Veritabanı bağlantısı
 * @param string $islem_tipi İşlem türü (ekle, guncelle, sil, giris, cikis)
 * @param string $tablo_adi İşlem yapılan tablo adı
 * @param int $kayit_id İşlem yapılan kayıt ID'si
 * @param array|null $eski_deger Eski değerler (güncelleme ve silme için)
 * @param array|null $yeni_deger Yeni değerler (ekleme ve güncelleme için)
 * @param string $aciklama İşlem açıklaması
 * @param int|null $kullanici_id İşlemi yapan kullanıcı ID'si
 * @return int|false Log ID'si veya false
 */
function sistem_log_ekle($db, $islem_tipi, $tablo_adi = null, $kayit_id = null, $eski_deger = null, $yeni_deger = null, $aciklama = '', $kullanici_id = null) {
    try {
        // Aktif şirket ID'sini session'dan al
        $sirket_id = $_SESSION['aktif_sirket_id'] ?? null;

        // Eğer sirket_id yoksa (kullanıcı giriş yapmamış/şirket seçmemişse) loglama yapma
        if ($sirket_id === null) {
            return false;
        }

        // Kullanıcı ID'sini session'dan al
        if ($kullanici_id === null && isset($_SESSION['kullanici_id'])) {
            $kullanici_id = $_SESSION['kullanici_id'];
        }
        
        // IP adresi ve User Agent bilgilerini al
        $ip_adresi = $_SERVER['REMOTE_ADDR'] ?? null;
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        
        // Değerleri JSON formatına çevir
        $eski_deger_json = $eski_deger ? json_encode($eski_deger, JSON_UNESCAPED_UNICODE) : null;
        $yeni_deger_json = $yeni_deger ? json_encode($yeni_deger, JSON_UNESCAPED_UNICODE) : null;
        
        $stmt = $db->prepare("
            INSERT INTO sistem_loglari 
            (kullanici_id, sirket_id, islem_tipi, tablo_adi, kayit_id, eski_deger, yeni_deger, aciklama, ip_adresi, user_agent) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $stmt->execute([
            $kullanici_id,
            $sirket_id,
            $islem_tipi,
            $tablo_adi,
            $kayit_id,
            $eski_deger_json,
            $yeni_deger_json,
            $aciklama,
            $ip_adresi,
            $user_agent
        ]);
        
        return $db->lastInsertId();
        
    } catch (Exception $e) {
        error_log("Log ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Oturum logu ekle
 * @param PDO $db Veritabanı bağlantısı
 * @param string $islem_tipi İşlem türü (giris, cikis, basarisiz_giris)
 * @param int|null $kullanici_id Kullanıcı ID'si
 * @return bool Başarı durumu
 */
function oturum_log_ekle($db, $islem_tipi, $kullanici_id = null) {
    try {
        // IP adresi ve User Agent bilgilerini al
        $ip_adresi = $_SERVER['REMOTE_ADDR'] ?? null;
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        
        // Session'dan aktif şirket ID'sini al, yoksa varsayılan şirket ID'sini kullan
        $sirket_id = $_SESSION['aktif_sirket_id'] ?? 1;
        
        // Eğer kullanıcı giriş yapmışsa ve şirket ilişkisi varsa, o şirketi kullan
        if ($kullanici_id && isset($_SESSION['kullanici_sirketleri']) && !empty($_SESSION['kullanici_sirketleri'])) {
            $sirket_id = $_SESSION['kullanici_sirketleri'][0]['id'] ?? 1;
        }
        
        $stmt = $db->prepare("
            INSERT INTO oturum_loglari (kullanici_id, sirket_id, islem_tipi, ip_adresi, user_agent) 
            VALUES (?, ?, ?, ?, ?)
        ");
        
        return $stmt->execute([$kullanici_id, $sirket_id, $islem_tipi, $ip_adresi, $user_agent]);
        
    } catch (Exception $e) {
        error_log("Oturum log ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Silinen kaydı geri alma için işaretle
 * @param PDO $db Veritabanı bağlantısı
 * @param int $log_id Sistem log ID'si
 * @param string $tablo_adi Tablo adı
 * @param int $kayit_id Kayıt ID'si
 * @param array $kayit_verisi Kayıt verisi
 * @return bool Başarı durumu
 */
function silinen_kayit_ekle($db, $log_id, $tablo_adi, $kayit_id, $kayit_verisi) {
    try {
        // sistem_loglari tablosunda geri_alindi alanı NULL olarak ayarla (geri alma mümkün)
        $stmt = $db->prepare("UPDATE sistem_loglari SET geri_alindi = NULL WHERE id = ? AND islem_tipi = 'sil'");
        
        return $stmt->execute([$log_id]);
        
    } catch (Exception $e) {
        error_log("Silinen kayıt işaretleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Silinen kaydı geri al
 * @param PDO $db Veritabanı bağlantısı
 * @param int $silinen_kayit_id Silinen kayıt ID'si (sistem_loglari tablosundaki id)
 * @return bool Başarı durumu
 */
function silinen_kayit_geri_al($db, $silinen_kayit_id) {
    try {
        $db->beginTransaction();
        
        // Silinen kayıt bilgilerini sistem_loglari tablosundan al
        $stmt = $db->prepare("SELECT * FROM sistem_loglari WHERE id = ? AND islem_tipi = 'sil' AND geri_alindi IS NULL");
        $stmt->execute([$silinen_kayit_id]);
        $silinen_kayit = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$silinen_kayit) {
            throw new Exception("Silinen kayıt bulunamadı veya zaten geri alınmış.");
        }
        
        $tablo_adi = $silinen_kayit['tablo_adi'];
        $kayit_verisi = json_decode($silinen_kayit['eski_deger'], true);
        $kayit_id = $silinen_kayit['kayit_id'];
        
        // Kayıt verisini geri ekle
        $kolonlar = array_keys($kayit_verisi);
        $degerler = array_values($kayit_verisi);
        $placeholders = str_repeat('?,', count($degerler) - 1) . '?';
        
        $sql = "INSERT INTO `{$tablo_adi}` (`" . implode('`, `', $kolonlar) . "`) VALUES ({$placeholders})";
        $stmt = $db->prepare($sql);
        $stmt->execute($degerler);
        
        // Silinen kayıt durumunu güncelle
        $stmt = $db->prepare("UPDATE sistem_loglari SET geri_alindi = 1, geri_alma_tarihi = NOW() WHERE id = ?");
        $stmt->execute([$silinen_kayit_id]);
        
        // Log ekle
        sistem_log_ekle($db, 'geri_al', $tablo_adi, $kayit_id, null, $kayit_verisi, "Silinen kayıt geri alındı");
        
        $db->commit();
        return true;
        
    } catch (Exception $e) {
        $db->rollBack();
        error_log("Kayıt geri alma hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Log kayıtlarını getir
 * @param PDO $db Veritabanı bağlantısı
 * @param array $filtreler Filtreleme seçenekleri
 * @param int $limit Kayıt limiti
 * @param int $offset Başlangıç noktası
 * @return array Log kayıtları
 */
function log_kayitlari_getir($db, $filtreler = [], $limit = 50, $offset = 0) {
    try {
        $where_conditions = [];
        $params = [];
        
        // Filtreleri uygula
        if (!empty($filtreler['kullanici_id'])) {
            $where_conditions[] = "sl.kullanici_id = ?";
            $params[] = $filtreler['kullanici_id'];
        }
        
        if (!empty($filtreler['islem_tipi'])) {
            $where_conditions[] = "sl.islem_tipi = ?";
            $params[] = $filtreler['islem_tipi'];
        }
        
        if (!empty($filtreler['tablo_adi'])) {
            $where_conditions[] = "sl.tablo_adi = ?";
            $params[] = $filtreler['tablo_adi'];
        }
        
        if (!empty($filtreler['baslangic_tarihi'])) {
            $where_conditions[] = "DATE(sl.olusturulma_tarihi) >= ?";
            $params[] = $filtreler['baslangic_tarihi'];
        }
        
        if (!empty($filtreler['bitis_tarihi'])) {
            $where_conditions[] = "DATE(sl.olusturulma_tarihi) <= ?";
            $params[] = $filtreler['bitis_tarihi'];
        }
        
        $where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';
        
        $sql = "
            SELECT 
                sl.*,
                k.ad_soyad as kullanici_adi
            FROM sistem_loglari sl
            LEFT JOIN kullanicilar k ON sl.kullanici_id = k.id
            {$where_clause}
            ORDER BY sl.olusturulma_tarihi DESC
            LIMIT ? OFFSET ?
        ";
        
        $params[] = $limit;
        $params[] = $offset;
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
        
    } catch (Exception $e) {
        error_log("Log kayıtları getirme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Log kayıt sayısını getir
 * @param PDO $db Veritabanı bağlantısı
 * @param array $filtreler Filtreleme seçenekleri
 * @return int Toplam kayıt sayısı
 */
function log_kayit_sayisi_getir($db, $filtreler = []) {
    try {
        $where_conditions = [];
        $params = [];
        
        // Filtreleri uygula (log_kayitlari_getir ile aynı)
        if (!empty($filtreler['kullanici_id'])) {
            $where_conditions[] = "kullanici_id = ?";
            $params[] = $filtreler['kullanici_id'];
        }
        
        if (!empty($filtreler['islem_tipi'])) {
            $where_conditions[] = "islem_tipi = ?";
            $params[] = $filtreler['islem_tipi'];
        }
        
        if (!empty($filtreler['tablo_adi'])) {
            $where_conditions[] = "tablo_adi = ?";
            $params[] = $filtreler['tablo_adi'];
        }
        
        if (!empty($filtreler['baslangic_tarihi'])) {
            $where_conditions[] = "DATE(olusturulma_tarihi) >= ?";
            $params[] = $filtreler['baslangic_tarihi'];
        }
        
        if (!empty($filtreler['bitis_tarihi'])) {
            $where_conditions[] = "DATE(olusturulma_tarihi) <= ?";
            $params[] = $filtreler['bitis_tarihi'];
        }
        
        $where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';
        
        $sql = "SELECT COUNT(*) FROM sistem_loglari {$where_clause}";
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        
        return $stmt->fetchColumn();
        
    } catch (Exception $e) {
        error_log("Log kayıt sayısı getirme hatası: " . $e->getMessage());
        return 0;
    }
}

/**
 * Oturum loglarını getir
 * @param PDO $db Veritabanı bağlantısı
 * @param array $filtreler Filtreleme seçenekleri
 * @param int $limit Kayıt limiti
 * @param int $offset Başlangıç noktası
 * @return array Oturum log kayıtları
 */
function oturum_loglari_getir($db, $filtreler = [], $limit = 50, $offset = 0) {
    try {
        $where_conditions = [];
        $params = [];
        
        // Filtreleri uygula
        if (!empty($filtreler['kullanici_id'])) {
            $where_conditions[] = "ol.kullanici_id = ?";
            $params[] = $filtreler['kullanici_id'];
        }
        
        if (!empty($filtreler['islem_tipi'])) {
            $where_conditions[] = "ol.islem_tipi = ?";
            $params[] = $filtreler['islem_tipi'];
        }
        
        if (!empty($filtreler['baslangic_tarihi'])) {
            $where_conditions[] = "DATE(ol.olusturulma_tarihi) >= ?";
            $params[] = $filtreler['baslangic_tarihi'];
        }
        
        if (!empty($filtreler['bitis_tarihi'])) {
            $where_conditions[] = "DATE(ol.olusturulma_tarihi) <= ?";
            $params[] = $filtreler['bitis_tarihi'];
        }
        
        $where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';
        
        $sql = "
            SELECT 
                ol.*,
                k.ad_soyad as kullanici_adi
            FROM oturum_loglari ol
            LEFT JOIN kullanicilar k ON ol.kullanici_id = k.id
            {$where_clause}
            ORDER BY ol.olusturulma_tarihi DESC
            LIMIT ? OFFSET ?
        ";
        
        $params[] = $limit;
        $params[] = $offset;
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
        
    } catch (Exception $e) {
        error_log("Oturum logları getirme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * İşlem türü açıklamalarını getir
 * @param string $islem_tipi İşlem türü
 * @return string Açıklama
 */
function islem_tipi_aciklama($islem_tipi) {
    $aciklamalar = [
        'ekle' => 'Ekleme',
        'guncelle' => 'Güncelleme',
        'sil' => 'Silme',
        'geri_al' => 'Geri Alma',
        'giris' => 'Giriş',
        'cikis' => 'Çıkış',
        'basarisiz_giris' => 'Başarısız Giriş',
        'transfer' => 'Para Transferi', // Eklendi
        'transfer_cikis' => 'Hesap Çıkış', // Eklendi ve metin değiştirildi
        'transfer_giris' => 'Hesap Giriş' // Eklendi ve metin değiştirildi
    ];
    
    return $aciklamalar[$islem_tipi] ?? $islem_tipi;
}

/**
 * Tablo adı açıklamalarını getir
 * @param string $tablo_adi Tablo adı
 * @return string Açıklama
 */
function tablo_adi_aciklama($tablo_adi) {
    $aciklamalar = [
        'urunler' => 'Ürünler',
        'cariler' => 'Cariler',
        'hesaplar' => 'Hesaplar',
        'kategoriler' => 'Kategoriler',
        'borclar' => 'Borçlar',
        'hesap_hareketleri' => 'Hesap Hareketleri',
        'kullanicilar' => 'Kullanıcılar',
        'fatura_detaylari' => 'Fatura Detayları'
    ];
    
    return $aciklamalar[$tablo_adi] ?? $tablo_adi;
}