<?php

/**
 * Kullanıcı Yönetimi Fonksiyonları
 * Kullanıcı ekleme, düzenleme, silme ve yetkilendirme işlemleri
 */

/**
 * Yeni kullanıcı ekle
 * @param PDO $db Veritabanı bağlantısı
 * @param array $kullanici_bilgileri Kullanıcı bilgileri
 * @return int|false Kullanıcı ID'si veya false
 */
function kullanici_ekle($db, $kullanici_bilgileri) {
    try {
        $db->beginTransaction();
        
        // Kullanıcı adı kontrolü
        $stmt = $db->prepare("SELECT id FROM kullanicilar WHERE kullanici_adi = ?");
        $stmt->execute([$kullanici_bilgileri['kullanici_adi']]);
        if ($stmt->fetch()) {
            throw new Exception("Bu kullanıcı adı zaten kullanılıyor.");
        }
        
        // E-posta kontrolü (varsa)
        if (!empty($kullanici_bilgileri['email'])) {
            $stmt = $db->prepare("SELECT id FROM kullanicilar WHERE email = ?");
            $stmt->execute([$kullanici_bilgileri['email']]);
            if ($stmt->fetch()) {
                throw new Exception("Bu e-posta adresi zaten kullanılıyor.");
            }
        }
        
        // Şifreyi hashle
        $sifre_hash = password_hash($kullanici_bilgileri['sifre'], PASSWORD_DEFAULT);
        
        // Yetkileri JSON formatına çevir
        $yetkiler_json = isset($kullanici_bilgileri['yetkiler']) ? 
            json_encode($kullanici_bilgileri['yetkiler'], JSON_UNESCAPED_UNICODE) : null;
        
        // Kullanıcıyı ekle
        $stmt = $db->prepare("
            INSERT INTO kullanicilar 
            (kullanici_adi, ad_soyad, email, sifre, yetki_seviyesi, yetkiler, aktif, olusturan_kullanici_id, aciklama) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $stmt->execute([
            $kullanici_bilgileri['kullanici_adi'],
            $kullanici_bilgileri['ad_soyad'],
            $kullanici_bilgileri['email'] ?? null,
            $sifre_hash,
            $kullanici_bilgileri['yetki_seviyesi'] ?? 'kullanici',
            $yetkiler_json,
            $kullanici_bilgileri['aktif'] ?? 1,
            $_SESSION['kullanici_id'] ?? null,
            $kullanici_bilgileri['aciklama'] ?? null
        ]);
        
        $kullanici_id = $db->lastInsertId();
        
        // Şifre geçmişine ekle (aktif şirket ID'si ile)
        $aktif_sirket_id = $_SESSION['aktif_sirket_id'] ?? null;
        if ($aktif_sirket_id) {
            $stmt = $db->prepare("INSERT INTO kullanici_sifre_gecmisi (kullanici_id, sifre_hash, sirket_id) VALUES (?, ?, ?)");
            $stmt->execute([$kullanici_id, $sifre_hash, $aktif_sirket_id]);
            
            // Kullanıcıyı aktif şirkete ata
            $stmt = $db->prepare("INSERT INTO kullanici_sirket_iliskisi (kullanici_id, sirket_id, rol) VALUES (?, ?, ?)");
            $stmt->execute([$kullanici_id, $aktif_sirket_id, 'kullanici']);
        }
        
        // Log ekle
        sistem_log_ekle($db, 'ekle', 'kullanicilar', $kullanici_id, null, $kullanici_bilgileri, 
            'Yeni kullanıcı eklendi: ' . $kullanici_bilgileri['kullanici_adi']);
        
        $db->commit();
        return $kullanici_id;
        
    } catch (Exception $e) {
        $db->rollBack();
        error_log("Kullanıcı ekleme hatası: " . $e->getMessage());
        throw $e;
    }
}

/**
 * Kullanıcı güncelle
 * @param PDO $db Veritabanı bağlantısı
 * @param int $kullanici_id Kullanıcı ID'si
 * @param array $kullanici_bilgileri Güncellenecek bilgiler
 * @return bool Başarı durumu
 */
function kullanici_guncelle($db, $kullanici_id, $kullanici_bilgileri) {
    try {
        $db->beginTransaction();
        
        // Mevcut kullanıcı bilgilerini al
        $stmt = $db->prepare("SELECT * FROM kullanicilar WHERE id = ?");
        $stmt->execute([$kullanici_id]);
        $eski_bilgiler = $stmt->fetch();
        
        if (!$eski_bilgiler) {
            throw new Exception("Kullanıcı bulunamadı.");
        }
        
        // Kullanıcı adı kontrolü (değiştirilmişse)
        if (isset($kullanici_bilgileri['kullanici_adi']) && 
            $kullanici_bilgileri['kullanici_adi'] !== $eski_bilgiler['kullanici_adi']) {
            $stmt = $db->prepare("SELECT id FROM kullanicilar WHERE kullanici_adi = ? AND id != ?");
            $stmt->execute([$kullanici_bilgileri['kullanici_adi'], $kullanici_id]);
            if ($stmt->fetch()) {
                throw new Exception("Bu kullanıcı adı zaten kullanılıyor.");
            }
        }
        
        // E-posta kontrolü (değiştirilmişse)
        if (isset($kullanici_bilgileri['email']) && 
            $kullanici_bilgileri['email'] !== $eski_bilgiler['email']) {
            $stmt = $db->prepare("SELECT id FROM kullanicilar WHERE email = ? AND id != ?");
            $stmt->execute([$kullanici_bilgileri['email'], $kullanici_id]);
            if ($stmt->fetch()) {
                throw new Exception("Bu e-posta adresi zaten kullanılıyor.");
            }
        }
        
        // Güncellenecek alanları hazırla
        $update_fields = [];
        $params = [];
        
        $allowed_fields = ['kullanici_adi', 'ad_soyad', 'email', 'yetki_seviyesi', 'aktif', 'aciklama'];
        
        foreach ($allowed_fields as $field) {
            if (isset($kullanici_bilgileri[$field])) {
                $update_fields[] = "$field = ?";
                $params[] = $kullanici_bilgileri[$field];
            }
        }
        
        // Yetkileri güncelle
        if (isset($kullanici_bilgileri['yetkiler'])) {
            $update_fields[] = "yetkiler = ?";
            $params[] = json_encode($kullanici_bilgileri['yetkiler'], JSON_UNESCAPED_UNICODE);
        }
        
        // Şifre güncellemesi
        if (!empty($kullanici_bilgileri['sifre'])) {
            $yeni_sifre_hash = password_hash($kullanici_bilgileri['sifre'], PASSWORD_DEFAULT);
            
            // Eski şifrelerle karşılaştır (aktif şirket için)
            $aktif_sirket_id = $_SESSION['aktif_sirket_id'] ?? null;
            if ($aktif_sirket_id) {
                $stmt = $db->prepare("SELECT sifre_hash FROM kullanici_sifre_gecmisi WHERE kullanici_id = ? AND sirket_id = ? ORDER BY olusturulma_tarihi DESC LIMIT 5");
                $stmt->execute([$kullanici_id, $aktif_sirket_id]);
                $eski_sifreler = $stmt->fetchAll(PDO::FETCH_COLUMN);
            } else {
                $eski_sifreler = [];
            }
            
            foreach ($eski_sifreler as $eski_sifre) {
                if (password_verify($kullanici_bilgileri['sifre'], $eski_sifre)) {
                    throw new Exception("Son 5 şifrenizden birini kullanamazsınız.");
                }
            }
            
            $update_fields[] = "sifre = ?";
            $params[] = $yeni_sifre_hash;
            
            // Şifre geçmişine ekle (aktif şirket ID'si ile)
            $aktif_sirket_id = $_SESSION['aktif_sirket_id'] ?? null;
            if ($aktif_sirket_id) {
                $stmt = $db->prepare("INSERT INTO kullanici_sifre_gecmisi (kullanici_id, sifre_hash, sirket_id) VALUES (?, ?, ?)");
                $stmt->execute([$kullanici_id, $yeni_sifre_hash, $aktif_sirket_id]);
            }
            
            // Eski şifre geçmişini temizle (son 10 tanesini tut, aktif şirket için)
            if ($aktif_sirket_id) {
                $stmt = $db->prepare("DELETE FROM kullanici_sifre_gecmisi WHERE kullanici_id = ? AND sirket_id = ? AND id NOT IN (SELECT id FROM (SELECT id FROM kullanici_sifre_gecmisi WHERE kullanici_id = ? AND sirket_id = ? ORDER BY olusturulma_tarihi DESC LIMIT 10) as temp)");
                $stmt->execute([$kullanici_id, $aktif_sirket_id, $kullanici_id, $aktif_sirket_id]);
            }
        }
        
        if (!empty($update_fields)) {
            $params[] = $kullanici_id;
            $sql = "UPDATE kullanicilar SET " . implode(', ', $update_fields) . " WHERE id = ?";
            $stmt = $db->prepare($sql);
            $stmt->execute($params);
        }
        
        // Log ekle
        sistem_log_ekle($db, 'guncelle', 'kullanicilar', $kullanici_id, $eski_bilgiler, $kullanici_bilgileri, 
            'Kullanıcı güncellendi: ' . $eski_bilgiler['kullanici_adi']);
        
        $db->commit();
        return true;
        
    } catch (Exception $e) {
        $db->rollBack();
        error_log("Kullanıcı güncelleme hatası: " . $e->getMessage());
        throw $e;
    }
}

/**
 * Kullanıcı sil
 * @param PDO $db Veritabanı bağlantısı
 * @param int $kullanici_id Kullanıcı ID'si
 * @return bool Başarı durumu
 */
function kullanici_sil($db, $kullanici_id) {
    try {
        $db->beginTransaction();
        
        // Mevcut kullanıcı bilgilerini al
        $stmt = $db->prepare("SELECT * FROM kullanicilar WHERE id = ?");
        $stmt->execute([$kullanici_id]);
        $kullanici_bilgileri = $stmt->fetch();
        
        if (!$kullanici_bilgileri) {
            throw new Exception("Kullanıcı bulunamadı.");
        }
        
        // Kendi kendini silmeyi engelle
        if ($kullanici_id == $_SESSION['kullanici_id']) {
            throw new Exception("Kendi hesabınızı silemezsiniz.");
        }
        
        // Son admin kullanıcısını silmeyi engelle
        if ($kullanici_bilgileri['yetki_seviyesi'] === 'admin') {
            $stmt = $db->prepare("SELECT COUNT(*) FROM kullanicilar WHERE yetki_seviyesi = 'admin' AND aktif = 1 AND id != ?");
            $stmt->execute([$kullanici_id]);
            $admin_sayisi = $stmt->fetchColumn();
            
            if ($admin_sayisi == 0) {
                throw new Exception("Son admin kullanıcısını silemezsiniz.");
            }
        }
        
        // Kullanıcıyı sil
        $stmt = $db->prepare("DELETE FROM kullanicilar WHERE id = ?");
        $stmt->execute([$kullanici_id]);
        
        // Log ekle
        $log_id = sistem_log_ekle($db, 'sil', 'kullanicilar', $kullanici_id, $kullanici_bilgileri, null, 
            'Kullanıcı silindi: ' . $kullanici_bilgileri['kullanici_adi']);
        
        // Silinen kayıt tablosuna ekle (geri alma için)
        if ($log_id) {
            silinen_kayit_ekle($db, $log_id, 'kullanicilar', $kullanici_id, $kullanici_bilgileri);
        }
        
        $db->commit();
        return true;
        
    } catch (Exception $e) {
        $db->rollBack();
        error_log("Kullanıcı silme hatası: " . $e->getMessage());
        throw $e;
    }
}

/**
 * Kullanıcı yetkilerini kontrol et
 * @param array $kullanici_yetkiler Kullanıcının yetkileri
 * @param string $yetki_adi Kontrol edilecek yetki
 * @return bool Yetki var mı?
 */
function yetki_kontrol($kullanici_yetkiler, $yetki_adi) {
    // Admin her şeyi yapabilir
    if (isset($kullanici_yetkiler['tum_yetkiler']) && $kullanici_yetkiler['tum_yetkiler']) {
        return true;
    }
    
    // Belirli yetki kontrolü
    return isset($kullanici_yetkiler[$yetki_adi]) && $kullanici_yetkiler[$yetki_adi];
}

/**
 * Kullanıcının yetki seviyesini kontrol et
 * @param string $gerekli_seviye Gerekli yetki seviyesi
 * @param string $kullanici_seviye Kullanıcının yetki seviyesi
 * @return bool Yetki yeterli mi?
 */
function yetki_seviyesi_kontrol($gerekli_seviye, $kullanici_seviye) {
    $seviye_hiyerarsisi = [
        'misafir' => 1,
        'kullanici' => 2,
        'yonetici' => 3,
        'admin' => 4
    ];
    
    $gerekli_puan = $seviye_hiyerarsisi[$gerekli_seviye] ?? 0;
    $kullanici_puan = $seviye_hiyerarsisi[$kullanici_seviye] ?? 0;
    
    return $kullanici_puan >= $gerekli_puan;
}

/**
 * Kullanıcıları listele
 * @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 Kullanıcı listesi
 */
function kullanicilari_listele($db, $filtreler = [], $limit = 50, $offset = 0) {
    try {
        $where_conditions = [];
        $params = [];
        
        // Şirket filtresi (zorunlu)
        if (!empty($filtreler['sirket_id'])) {
            $where_conditions[] = "k.id IN (SELECT kullanici_id FROM kullanici_sirket_iliskisi WHERE sirket_id = ?)";
            $params[] = $filtreler['sirket_id'];
        }
        
        // Filtreleri uygula
        if (!empty($filtreler['yetki_seviyesi'])) {
            $where_conditions[] = "k.yetki_seviyesi = ?";
            $params[] = $filtreler['yetki_seviyesi'];
        }
        
        if (isset($filtreler['aktif'])) {
            $where_conditions[] = "k.aktif = ?";
            $params[] = $filtreler['aktif'];
        }
        
        if (!empty($filtreler['arama'])) {
            $where_conditions[] = "(k.kullanici_adi LIKE ? OR k.ad_soyad LIKE ? OR k.email LIKE ?)";
            $arama = '%' . $filtreler['arama'] . '%';
            $params[] = $arama;
            $params[] = $arama;
            $params[] = $arama;
        }
        
        $where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';
        
        $sql = "
            SELECT 
                k.*,
                ok.ad_soyad as olusturan_ad_soyad,
                (SELECT COUNT(*) FROM oturum_loglari ol WHERE ol.kullanici_id = k.id AND ol.islem_tipi = 'giris') as giris_sayisi,
                (SELECT MAX(ol.olusturulma_tarihi) FROM oturum_loglari ol WHERE ol.kullanici_id = k.id AND ol.islem_tipi = 'giris') as son_giris_tarihi
            FROM kullanicilar k
            LEFT JOIN kullanicilar ok ON k.olusturan_kullanici_id = ok.id
            {$where_clause}
            ORDER BY k.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("Kullanıcı listeleme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Kullanıcı sayısını getir
 * @param PDO $db Veritabanı bağlantısı
 * @param array $filtreler Filtreleme seçenekleri
 * @return int Toplam kullanıcı sayısı
 */
function kullanici_sayisi_getir($db, $filtreler = []) {
    try {
        $where_conditions = [];
        $params = [];
        
        // Şirket filtresi (zorunlu)
        if (!empty($filtreler['sirket_id'])) {
            $where_conditions[] = "k.id IN (SELECT kullanici_id FROM kullanici_sirket_iliskisi WHERE sirket_id = ?)";
            $params[] = $filtreler['sirket_id'];
        }
        
        // Filtreleri uygula (kullanicilari_listele ile aynı)
        if (!empty($filtreler['yetki_seviyesi'])) {
            $where_conditions[] = "k.yetki_seviyesi = ?";
            $params[] = $filtreler['yetki_seviyesi'];
        }
        
        if (isset($filtreler['aktif'])) {
            $where_conditions[] = "k.aktif = ?";
            $params[] = $filtreler['aktif'];
        }
        
        if (!empty($filtreler['arama'])) {
            $where_conditions[] = "(k.kullanici_adi LIKE ? OR k.ad_soyad LIKE ? OR k.email LIKE ?)";
            $arama = '%' . $filtreler['arama'] . '%';
            $params[] = $arama;
            $params[] = $arama;
            $params[] = $arama;
        }
        
        $where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';
        
        $sql = "SELECT COUNT(*) FROM kullanicilar k {$where_clause}";
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        
        return $stmt->fetchColumn();
        
    } catch (Exception $e) {
        error_log("Kullanıcı sayısı getirme hatası: " . $e->getMessage());
        return 0;
    }
}

/**
 * Aktif oturum ekle
 * @param PDO $db Veritabanı bağlantısı
 * @param int $kullanici_id Kullanıcı ID'si
 * @param string $session_id Oturum ID'si
 * @return bool Başarı durumu
 */
function aktif_oturum_ekle($db, $kullanici_id, $session_id, $sirket_id) {
    // sirket_id geçerli bir sayı değilse, işlemi durdur
    if (!is_numeric($sirket_id) || $sirket_id <= 0) {
        error_log("Aktif oturum ekleme hatası: Geçersiz sirket_id ($sirket_id)");
        return false;
    }

    try {
        $ip_adresi = $_SERVER['REMOTE_ADDR'] ?? null;
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        
        $stmt = $db->prepare("
            INSERT INTO aktif_oturumlar (kullanici_id, session_id, sirket_id, ip_adresi, user_agent) 
            VALUES (?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE 
            son_aktivite = CURRENT_TIMESTAMP,
            sirket_id = VALUES(sirket_id),
            ip_adresi = VALUES(ip_adresi),
            user_agent = VALUES(user_agent)
        ");
        
        return $stmt->execute([$kullanici_id, $session_id, $sirket_id, $ip_adresi, $user_agent]);
        
    } catch (Exception $e) {
        error_log("Aktif oturum ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Aktif oturum sil
 * @param PDO $db Veritabanı bağlantısı
 * @param string $session_id Oturum ID'si
 * @return bool Başarı durumu
 */
function aktif_oturum_sil($db, $session_id) {
    try {
        $stmt = $db->prepare("DELETE FROM aktif_oturumlar WHERE session_id = ?");
        return $stmt->execute([$session_id]);
        
    } catch (Exception $e) {
        error_log("Aktif oturum silme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Eski oturumları temizle
 * @param PDO $db Veritabanı bağlantısı
 * @param int $saat Kaç saat öncesini temizle
 * @return bool Başarı durumu
 */
function eski_oturumlari_temizle($db, $saat = 24) {
    try {
        $stmt = $db->prepare("DELETE FROM aktif_oturumlar WHERE son_aktivite < DATE_SUB(NOW(), INTERVAL ? HOUR)");
        return $stmt->execute([$saat]);
        
    } catch (Exception $e) {
        error_log("Eski oturum temizleme hatası: " . $e->getMessage());
        return false;
    }
}

