<?php
// Stok yönetimi için yardımcı fonksiyonlar

/**
 * Ürün ekle
 * @param PDO $db
 * @param array $urun_bilgileri
 * @param int $sirket_id
 * @return int|false
 */
function urunEkle($db, $urun_bilgileri, $sirket_id) {
    try {
        $sql = "INSERT INTO urunler (sirket_id, urun_adi, barkod, kategori_id, birim, alis_fiyati, satis_fiyati, kdv_orani, alis_fiyati2, satis_fiyati2, kdv_orani2, kritik_stok, mevcut_stok_baslangic, aciklama, alis_para_birimi, satis_para_birimi)
                VALUES (:sirket_id, :urun_adi, :barkod, :kategori_id, :birim, :alis_fiyati, :satis_fiyati, :kdv_orani, :alis_fiyati2, :satis_fiyati2, :kdv_orani2, :kritik_stok, :mevcut_stok_baslangic, :aciklama, :alis_para_birimi, :satis_para_birimi)";
        
        $stmt = $db->prepare($sql);
        $stmt->execute([
            ':sirket_id' => $sirket_id,
            ':urun_adi' => $urun_bilgileri['urun_adi'],
            ':barkod' => $urun_bilgileri['barkod'] ?: null,
            ':kategori_id' => $urun_bilgileri['kategori_id'] ?: null,
            ':birim' => $urun_bilgileri['birim'] ?? 'adet',
            ':alis_fiyati' => $urun_bilgileri['alis_fiyati'] ?? 0.00,
            ':satis_fiyati' => $urun_bilgileri['satis_fiyati'] ?? 0.00,
            ':kdv_orani' => $urun_bilgileri['kdv_orani'] ?? 0.00,
            ':alis_fiyati2' => $urun_bilgileri['alis_fiyati2'] ?? 0.00,
            ':satis_fiyati2' => $urun_bilgileri['satis_fiyati2'] ?? 0.00,
            ':kdv_orani2' => $urun_bilgileri['kdv_orani2'] ?? 0.00,
            ':kritik_stok' => $urun_bilgileri['kritik_stok'] ?? 0,
            ':mevcut_stok_baslangic' => $urun_bilgileri['mevcut_stok_baslangic'] ?? 0,
            ':aciklama' => $urun_bilgileri['aciklama'] ?? null,
            ':alis_para_birimi' => $urun_bilgileri['alis_para_birimi'] ?? 'TL',
            ':satis_para_birimi' => $urun_bilgileri['satis_para_birimi'] ?? 'TL'
        ]);
        
        $urun_id = $db->lastInsertId();
        
        // Mevcut stok kaydı oluştur
        $stmt_stok = $db->prepare("INSERT INTO mevcut_stok (urun_id, sirket_id, miktar, ortalama_maliyet) VALUES (?, ?, ?, ?)");
        $stmt_stok->execute([$urun_id, $sirket_id, $urun_bilgileri['mevcut_stok_baslangic'], $urun_bilgileri['alis_fiyati']]);
        
        // Log ekle
        sistem_log_ekle($db, 'ekle', 'urunler', $urun_id, $sirket_id, $urun_bilgileri, 'Yeni ürün eklendi: ' . $urun_bilgileri['urun_adi']);
        
        return $urun_id;
    } catch (PDOException $e) {
        error_log("Ürün ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Stok hareketi ekle
 */
function stokHareketiEkle(PDO $db, array $hareket_bilgileri): bool {
    try {
        $db->beginTransaction();
        
        // Stok hareketi kaydet
        $sql = "INSERT INTO stok_hareketleri (urun_id, hareket_turu, miktar, birim_fiyat, toplam_tutar, aciklama, borc_id, cari_id, kullanici_id, sirket_id)
                VALUES (:urun_id, :hareket_turu, :miktar, :birim_fiyat, :toplam_tutar, :aciklama, :borc_id, :cari_id, :kullanici_id, :sirket_id)";
        
        $stmt = $db->prepare($sql);
        $stmt->execute([
            ':urun_id' => $hareket_bilgileri['urun_id'],
            ':hareket_turu' => $hareket_bilgileri['hareket_turu'],
            ':miktar' => $hareket_bilgileri['miktar'],
            ':birim_fiyat' => $hareket_bilgileri['birim_fiyat'] ?? null,
            ':toplam_tutar' => $hareket_bilgileri['toplam_tutar'] ?? null,
            ':aciklama' => $hareket_bilgileri['aciklama'] ?? null,
            ':borc_id' => $hareket_bilgileri['borc_id'] ?? null,
            ':cari_id' => $hareket_bilgileri['cari_id'] ?? null,
            ':kullanici_id' => $_SESSION['kullanici_id'] ?? null,
            ':sirket_id' => $_SESSION['aktif_sirket_id']
        ]);
        
        // Mevcut stok güncelle
        $miktar_degisim = ($hareket_bilgileri['hareket_turu'] == 'giris' || $hareket_bilgileri['hareket_turu'] == 'sayim') 
            ? $hareket_bilgileri['miktar'] 
            : -$hareket_bilgileri['miktar'];
            
        if (!stokGuncelle($db, $hareket_bilgileri['urun_id'], $miktar_degisim, $hareket_bilgileri['birim_fiyat'] ?? null)) {
            throw new Exception("Stok güncellenemedi");
        }
        
        $db->commit();
        return true;
    } catch (Exception $e) {
        $db->rollBack();
        error_log("Stok hareketi ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Mevcut stok güncelle
 */
function stokGuncelle(PDO $db, int $urun_id, float $miktar_degisim, ?float $birim_fiyat = null, ?string $aciklama = null, ?int $referans_id = null, ?string $referans_tipi = null): bool {
    try {
        // Mevcut stok bilgisini al
        $stmt = $db->prepare("SELECT miktar, ortalama_maliyet FROM mevcut_stok WHERE urun_id = ? AND sirket_id = ?");
        $stmt->execute([$urun_id, $_SESSION['aktif_sirket_id']]);
        $mevcut = $stmt->fetch();
        
        $yeni_miktar = 0;
        $yeni_maliyet = 0;
        $islem_tipi = $miktar_degisim > 0 ? 'stok_giris' : 'stok_cikis';
        
        if (!$mevcut) {
            // Stok kaydı yoksa oluştur
            $yeni_miktar = max(0, $miktar_degisim);
            $yeni_maliyet = $birim_fiyat ?? 0.00;
            
            $stmt = $db->prepare("INSERT INTO mevcut_stok (urun_id, sirket_id, miktar, ortalama_maliyet) VALUES (?, ?, ?, ?)");
            $result = $stmt->execute([$urun_id, $_SESSION['aktif_sirket_id'], $yeni_miktar, $yeni_maliyet]);
            
            // Stok hareketini logla
            if ($result && function_exists('sistem_log_ekle')) {
                $hareket_aciklama = $aciklama ?: "Stok oluşturuldu. Miktar: " . $yeni_miktar;
                if ($referans_id && $referans_tipi) {
                    $hareket_aciklama .= " (Referans: {$referans_tipi} #{$referans_id})";
                }
                sistem_log_ekle($db, $islem_tipi, 'mevcut_stok', $urun_id, null, 
                    ['miktar' => $yeni_miktar, 'ortalama_maliyet' => $yeni_maliyet], 
                    $hareket_aciklama
                );
            }
            
            return $result;
        }
        
        $yeni_miktar = max(0, $mevcut['miktar'] + $miktar_degisim);
        $yeni_maliyet = $mevcut['ortalama_maliyet'];
        
        // Giriş işleminde ortalama maliyeti güncelle (FIFO mantığı)
        if ($miktar_degisim > 0 && $birim_fiyat !== null && $birim_fiyat > 0) {
            $toplam_maliyet = ($mevcut['miktar'] * $mevcut['ortalama_maliyet']) + ($miktar_degisim * $birim_fiyat);
            $yeni_maliyet = $yeni_miktar > 0 ? $toplam_maliyet / $yeni_miktar : 0;
        }
        
        $stmt = $db->prepare("UPDATE mevcut_stok SET miktar = ?, ortalama_maliyet = ? WHERE urun_id = ? AND sirket_id = ?");
        $result = $stmt->execute([$yeni_miktar, $yeni_maliyet, $urun_id, $_SESSION['aktif_sirket_id']]);
        
        // Stok hareketini logla
        if ($result && function_exists('sistem_log_ekle')) {
            $hareket_aciklama = $aciklama ?: ($miktar_degisim > 0 ? 'Stok girişi yapıldı' : 'Stok çıkışı yapıldı');
            $hareket_aciklama .= ". Miktar: " . abs($miktar_degisim) . ", Yeni Miktar: " . $yeni_miktar;
            
            if ($referans_id && $referans_tipi) {
                $hareket_aciklama .= " (Referans: {$referans_tipi} #{$referans_id})";
            }
            
            sistem_log_ekle($db, $islem_tipi, 'mevcut_stok', $urun_id, 
                ['miktar' => $mevcut['miktar'], 'ortalama_maliyet' => $mevcut['ortalama_maliyet']], 
                ['miktar' => $yeni_miktar, 'ortalama_maliyet' => $yeni_maliyet], 
                $hareket_aciklama
            );
        }
        
        return $result;
        
    } catch (PDOException $e) {
        error_log("Stok güncelleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Barkod ile ürün ara
 * @param PDO $db
 * @param string $barkod
 * @param int $sirket_id
 * @param int|null $tedarikci_id
 * @return array|false
 */
function barkodIleUrunAra($db, $barkod, $sirket_id, $tedarikci_id = null) {
    try {
        $sql = "
            SELECT u.*, ms.miktar as stok_miktari, ms.ortalama_maliyet, k.kategori_adi
            FROM urunler u
            LEFT JOIN mevcut_stok ms ON u.id = ms.urun_id AND ms.sirket_id = u.sirket_id
            LEFT JOIN kategoriler k ON u.kategori_id = k.id AND k.sirket_id = u.sirket_id
            WHERE u.barkod = ? AND u.sirket_id = ? AND u.aktif = 1";
        
        $params = [$barkod, $sirket_id];
        
        // Tedarikçi filtresi varsa ekle
        if ($tedarikci_id) {
            $sql .= " AND u.tedarikci_id = ?";
            $params[] = $tedarikci_id;
        }
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetch() ?: false;
    } catch (PDOException $e) {
        error_log("Barkod arama hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Ürün ara (ad ile)
 */
function urunAra(PDO $db, string $arama_terimi, int $sirket_id, int $limit = 20, ?int $tedarikci_id = null): array {
    try {
        $sql = "
            SELECT u.*, ms.miktar as stok_miktari, ms.ortalama_maliyet, k.kategori_adi
            FROM urunler u
            LEFT JOIN mevcut_stok ms ON u.id = ms.urun_id AND ms.sirket_id = u.sirket_id
            LEFT JOIN kategoriler k ON u.kategori_id = k.id AND k.sirket_id = u.sirket_id
            WHERE u.urun_adi LIKE ? AND u.sirket_id = ? AND u.aktif = 1";
        
        $params = ['%' . $arama_terimi . '%', $sirket_id];
        
        // Tedarikçi filtresi varsa ekle
        if ($tedarikci_id) {
            $sql .= " AND u.tedarikci_id = ?";
            $params[] = $tedarikci_id;
        }
        
        $sql .= " ORDER BY u.urun_adi LIMIT ?";
        $params[] = $limit;
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Ürün arama hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Kritik stok listesi
 */
function kritikStokListesi(PDO $db, int $sirket_id): array {
    try {
        $stmt = $db->prepare("
            SELECT u.*, ms.miktar as stok_miktari, k.kategori_adi
            FROM urunler u
            LEFT JOIN mevcut_stok ms ON u.id = ms.urun_id AND ms.sirket_id = u.sirket_id
            LEFT JOIN kategoriler k ON u.kategori_id = k.id AND k.sirket_id = u.sirket_id
            WHERE u.sirket_id = ? AND u.aktif = 1 AND ms.miktar <= u.kritik_stok AND u.kritik_stok > 0
            ORDER BY (ms.miktar - u.kritik_stok) ASC
        ");
        $stmt->execute([$sirket_id]);
        return $stmt->fetchAll();
    } catch (PDOException $e) {
        error_log("Kritik stok listesi hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Fatura detayı ekle - PRODUCTION GRADE
 * 
 * TaxEngine + DiscountEngine kullanarak deterministik hesaplama
 * Integer arithmetic - ZERO float error
 * 
 * @param PDO $db Veritabanı bağlantısı
 * @param int $borc_id Fatura ID
 * @param array $detaylar Satır detayları
 * @param int $sirket_id Şirket ID
 * @param int $global_indirim_kurus Global indirim (kuruş)
 * @return bool Başarılı mı?
 */
function faturaDetayiEkle(PDO $db, int $borc_id, array $detaylar, int $sirket_id, int $global_indirim_kurus = 0): bool {
    try {
        require_once __DIR__ . '/../classes/MoneyHelper.php';
        require_once __DIR__ . '/../classes/TaxEngine.php';
        require_once __DIR__ . '/../classes/DiscountEngine.php';
        
        // Transaction zaten başlatılmış olmalı
        
        // KDV hesaplama tipini al
        $kdv_tipi = getKdvHesaplamaTipi($db, $sirket_id);
        
        // Faturanın para birimini al
        $stmt_pb = $db->prepare("SELECT para_birimi FROM borclar WHERE id = ?");
        $stmt_pb->execute([$borc_id]);
        $fatura_para_birimi = $stmt_pb->fetchColumn() ?: 'TRY';
        
        // Satır kalemlerini hazırla
        $lineItems = [];
        foreach ($detaylar as $detay) {
            $lineItems[] = [
                'unit_price' => $detay['birim_fiyat_kurus'], // Kuruş
                'quantity' => (int) $detay['miktar'], // Integer
                'vat_rate_basis' => TaxEngine::percentToBasis($detay['kdv_orani']), // Basis points
                'line_discount' => $detay['satir_indirimi'] ?? 0, // Kuruş
                'urun_id' => $detay['urun_id'],
                'cari_id' => $detay['cari_id'] ?? null,
                'islem_turu' => $detay['islem_turu'] ?? 'satis',
                'kur' => $detay['kur'] ?? 1.0
            ];
        }
        
        // TaxEngine ile hesapla (STATELESS + AUDIT MODE)
        $inputType = ($kdv_tipi === 'kdv_dahil') ? 'gross' : 'net';
        $roundingStrategy = 'HALF_UP'; // Türkiye standardı
        $auditMode = true; // Audit trail aktif
        
        $calculation = TaxEngine::calculateInvoice(
            $lineItems, 
            $inputType,
            $global_indirim_kurus,
            $roundingStrategy,
            $auditMode
        );
        
        // Her satırı kaydet
        $stmt = $db->prepare("INSERT INTO fatura_detaylari 
            (borc_id, urun_id, sirket_id, miktar, 
             birim_fiyat, birim_fiyat_kurus,
             kdv_orani, kdv_orani_basis,
             kdv_tutari, kdv_tutari_kurus,
             toplam_tutar, toplam_tutar_kurus,
             satir_indirimi, dagitilan_indirim, kdv_telafi_tutari,
             para_birimi, kur)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        
        foreach ($calculation['lines'] as $index => $line) {
            $detay = $detaylar[$index];
            
            // Eski decimal değerler (geriye uyumluluk için)
            $birim_fiyat_decimal = MoneyHelper::toTL($line['unit_price_net']);
            $kdv_tutari_decimal = MoneyHelper::toTL($line['line_vat']);
            $toplam_tutar_decimal = MoneyHelper::toTL($line['line_net_final']);
            $kdv_orani_decimal = TaxEngine::basisToPercent($line['vat_rate_basis']);
            
            $stmt->execute([
                $borc_id,
                $detay['urun_id'],
                $sirket_id,
                $line['quantity'],
                $birim_fiyat_decimal, // Eski decimal
                $line['unit_price_net'], // Yeni kuruş
                $kdv_orani_decimal, // Eski yüzde
                $line['vat_rate_basis'], // Yeni basis points
                $kdv_tutari_decimal, // Eski decimal
                $line['line_vat'], // Yeni kuruş
                $toplam_tutar_decimal, // Eski decimal
                $line['line_net_final'], // Yeni kuruş
                $line['line_discount'], // Satır indirimi (kuruş)
                $line['distributed_discount'], // Global indirimden pay (kuruş)
                $line['compensation'], // Telafi tutarı (kuruş)
                $fatura_para_birimi,
                $detay['kur'] ?? 1.0
            ]);
            
            // Stok hareketini kaydet
            $hareket_turu = $detay['islem_turu'] == 'satis' ? 'cikis' : 'giris';
            $stok_hareket = [
                'urun_id' => $detay['urun_id'],
                'hareket_turu' => $hareket_turu,
                'miktar' => $line['quantity'],
                'birim_fiyat' => $birim_fiyat_decimal,
                'toplam_tutar' => $toplam_tutar_decimal,
                'aciklama' => $detay['islem_turu'] == 'satis' ? 'Satış' : 'Alış',
                'borc_id' => $borc_id,
                'cari_id' => $detay['cari_id'] ?? null,
                'sirket_id' => $sirket_id
            ];
            
            if (!stokHareketiEkleBasit($db, $stok_hareket)) {
                throw new Exception("Stok hareketi eklenemedi");
            }
        }
        
        // Ana fatura kaydını güncelle (hem eski hem yeni değerler)
        $stmt_update = $db->prepare("UPDATE borclar 
            SET tutar = ?, tutar_kurus = ?,
                toplam_kdv = ?, toplam_kdv_kurus = ?,
                indirim_tutari = ?, indirim_tutari_kurus = ?
            WHERE id = ?");
        $stmt_update->execute([
            MoneyHelper::toTL($calculation['total_net']),
            $calculation['total_net'],
            MoneyHelper::toTL($calculation['total_vat']),
            $calculation['total_vat'],
            MoneyHelper::toTL($calculation['global_discount']),
            $calculation['global_discount'],
            $borc_id
        ]);
        
        return true;
    } catch (Exception $e) {
        error_log("Fatura detayı ekleme hatası: " . $e->getMessage());
        error_log("Stack trace: " . $e->getTraceAsString());
        return false;
    }
}

/**
 * Stok durumu raporu
 */
function stokDurumuRaporu(PDO $db, int $sirket_id): array {
    try {
        $stmt = $db->prepare("
            SELECT 
                u.id,
                u.urun_adi,
                u.barkod,
                u.birim,
                u.kritik_stok,
                ms.miktar as stok_miktari,
                ms.ortalama_maliyet,
                (ms.miktar * ms.ortalama_maliyet) as toplam_deger,
                k.kategori_adi,
                CASE 
                    WHEN ms.miktar <= 0 THEN 'Stokta Yok'
                    WHEN ms.miktar <= u.kritik_stok AND u.kritik_stok > 0 THEN 'Kritik Seviye'
                    ELSE 'Normal'
                END as stok_durumu
            FROM urunler u
            LEFT JOIN mevcut_stok ms ON u.id = ms.urun_id AND ms.sirket_id = u.sirket_id
            LEFT JOIN kategoriler k ON u.kategori_id = k.id AND k.sirket_id = u.sirket_id
            WHERE u.sirket_id = ? AND u.aktif = 1
            ORDER BY u.urun_adi
        ");
        $stmt->execute([$sirket_id]);
        return $stmt->fetchAll();
    } catch (PDOException $e) {
        error_log("Stok durumu raporu hatası: " . $e->getMessage());
        return [];
    }
}



/**
 * Ürün güncelle
 */
function urunGuncelle(PDO $db, int $urun_id, int $sirket_id, array $urun_bilgileri): bool {
    try {
        $sql = "UPDATE urunler SET 
                    urun_adi = :urun_adi,
                    barkod = :barkod,
                    kategori_id = :kategori_id,
                    birim = :birim,
                    alis_fiyati = :alis_fiyati,
                    satis_fiyati = :satis_fiyati,
                    kdv_orani = :kdv_orani,
                    alis_fiyati2 = :alis_fiyati2,
                    satis_fiyati2 = :satis_fiyati2,
                    kdv_orani2 = :kdv_orani2,
                    kritik_stok = :kritik_stok,
                    mevcut_stok_baslangic = :mevcut_stok_baslangic,
                    aciklama = :aciklama,
                    alis_para_birimi = :alis_para_birimi,
                    satis_para_birimi = :satis_para_birimi,
                    guncelleme_tarihi = NOW()
                WHERE id = :urun_id AND sirket_id = :sirket_id AND aktif = 1";
        
        $stmt = $db->prepare($sql);
        return $stmt->execute([
            ':urun_id' => $urun_id,
            ':sirket_id' => $sirket_id,
            ':urun_adi' => $urun_bilgileri['urun_adi'],
            ':barkod' => $urun_bilgileri['barkod'] ?: null,
            ':kategori_id' => $urun_bilgileri['kategori_id'] ?: null,
            ':birim' => $urun_bilgileri['birim'] ?? 'adet',
            ':alis_fiyati' => $urun_bilgileri['alis_fiyati'] ?? 0.00,
            ':satis_fiyati' => $urun_bilgileri['satis_fiyati'] ?? 0.00,
            ':kdv_orani' => $urun_bilgileri['kdv_orani'] ?? 0.00,
            ':alis_fiyati2' => $urun_bilgileri['alis_fiyati2'] ?? 0.00,
            ':satis_fiyati2' => $urun_bilgileri['satis_fiyati2'] ?? 0.00,
            ':kdv_orani2' => $urun_bilgileri['kdv_orani2'] ?? 0.00,
            ":kritik_stok" => $urun_bilgileri["kritik_stok"] ?? 0,
            ":mevcut_stok_baslangic" => $urun_bilgileri["mevcut_stok_baslangic"] ?? 0,
            ':aciklama' => $urun_bilgileri["aciklama"] ?? null,
            ':alis_para_birimi' => $urun_bilgileri['alis_para_birimi'] ?? 'TL',
            ':satis_para_birimi' => $urun_bilgileri['satis_para_birimi'] ?? 'TL'
        ]);
    } catch (PDOException $e) {
        error_log("Ürün güncelleme hatası: " . $e->getMessage());
        return false;
    }
}


/**
 * Stok hareketi ekle (Basit versiyon - Transaction kullanmadan)
 */
function stokHareketiEkleBasit(PDO $db, array $hareket_bilgileri): bool {
    try {
        // Stok hareketi kaydet
        $sql = "INSERT INTO stok_hareketleri (urun_id, hareket_turu, miktar, birim_fiyat, toplam_tutar, aciklama, borc_id, cari_id, kullanici_id, sirket_id)
                VALUES (:urun_id, :hareket_turu, :miktar, :birim_fiyat, :toplam_tutar, :aciklama, :borc_id, :cari_id, :kullanici_id, :sirket_id)";
        
        $stmt = $db->prepare($sql);
        $stmt->execute([
            ':urun_id' => $hareket_bilgileri['urun_id'],
            ':hareket_turu' => $hareket_bilgileri['hareket_turu'],
            ':miktar' => $hareket_bilgileri['miktar'],
            ':birim_fiyat' => $hareket_bilgileri['birim_fiyat'] ?? null,
            ':toplam_tutar' => $hareket_bilgileri['toplam_tutar'] ?? null,
            ':aciklama' => $hareket_bilgileri['aciklama'] ?? null,
            ':borc_id' => $hareket_bilgileri['borc_id'] ?? null,
            ':cari_id' => $hareket_bilgileri['cari_id'] ?? null,
            ':kullanici_id' => $_SESSION['kullanici_id'] ?? null,
            ':sirket_id' => $_SESSION['aktif_sirket_id']
        ]);
        
        return true;
    } catch (PDOException $e) {
        error_log("Stok hareketi ekleme hatası (basit): " . $e->getMessage());
        return false;
    }
}



/**
 * Resim yükleme fonksiyonu
 */
function resimYukle(PDO $db, int $urun_id, int $sirket_id, array $files, string $db_yukleme_dizini): bool {
    // Projenin kök dizinini temel alan GÜVENLİ ve DİNAMİK bir yükleme yolu oluştur.
    // Bu, veritabanındaki ayardan daha güvenilirdir ve projenin taşınabilirliğini sağlar.
    $yukleme_dizini = __DIR__ . '/../uploads/urun_resimleri';

    // Dizin var mı ve yazılabilir mi kontrol et
    if (!is_dir($yukleme_dizini)) {
        if (!mkdir($yukleme_dizini, 0755, true)) {
            error_log("Yükleme dizini oluşturulamadı: " . $yukleme_dizini);
            $_SESSION['hata'] = "Sunucuda resim yükleme klasörü hazırlanamadı.";
            return false;
        }
    }
    if (!is_writable($yukleme_dizini)) {
        error_log("Yükleme dizini yazılabilir değil: " . $yukleme_dizini);
        $_SESSION['hata'] = "Sunucudaki resim yükleme klasörüne yazma izni yok.";
        return false;
    }

    try {
        $stmt = $db->prepare("INSERT INTO urun_resimleri (urun_id, sirket_id, resim_yolu) VALUES (?, ?, ?)");
        
        foreach ($files['name'] as $key => $name) {
            if ($files['error'][$key] === UPLOAD_ERR_OK) {
                $orijinal_dosya_adi = basename($name);
                $uzanti = strtolower(pathinfo($orijinal_dosya_adi, PATHINFO_EXTENSION));

                // Güvenlik: Sadece izin verilen uzantıları kabul et
                $izin_verilen_uzantilar = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
                if (!in_array($uzanti, $izin_verilen_uzantilar)) {
                    continue; // Geçersiz uzantıyı atla
                }

                $yeni_dosya_adi = uniqid(rand(), true) . '_' . $orijinal_dosya_adi;
                $hedef_dosya_tam_yol = $yukleme_dizini . '/' . $yeni_dosya_adi;
                
                // Veritabanına kaydedilecek göreli yol
                $db_yolu = 'uploads/urun_resimleri/' . $yeni_dosya_adi;

                if (move_uploaded_file($files['tmp_name'][$key], $hedef_dosya_tam_yol)) {
                    // Veritabanına göreli yolu kaydet
                    $stmt->execute([$urun_id, $sirket_id, $db_yolu]);
                } else {
                    error_log("Dosya taşınamadı: " . $orijinal_dosya_adi . " -> " . $hedef_dosya_tam_yol);
                }
            }
        }
        return true;
    } catch (PDOException $e) {
        error_log("Resim veritabanına kaydedilemedi: " . $e->getMessage());
        return false;
    }
}

/**
 * Ürüne ait resimleri getirir
 */
function urunResimleriniGetir(PDO $db, int $urun_id, int $sirket_id): array {
    try {
        $stmt = $db->prepare("SELECT id, resim_yolu, varsayilan FROM urun_resimleri WHERE urun_id = ? AND sirket_id = ? ORDER BY varsayilan DESC, id ASC");
        $stmt->execute([$urun_id, $sirket_id]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Ürün resimleri getirilirken hata oluştu: " . $e->getMessage());
        return [];
    }
}

/**
 * Ürün resmini sil
 */
function urunResmiSil(PDO $db, int $resim_id, int $sirket_id): bool {
    try {
        // Önce resmi veritabanından bul
        $stmt = $db->prepare("SELECT resim_yolu, urun_id FROM urun_resimleri WHERE id = ? AND sirket_id = ?");
        $stmt->execute([$resim_id, $sirket_id]);
        $resim = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($resim) {
            // Fiziksel dosyayı sil
            $proje_koku = dirname(__DIR__); // functions klasörünün bir üstü
            $fiziksel_yol = $proje_koku . '/' . $resim['resim_yolu'];

            if (file_exists($fiziksel_yol)) {
                unlink($fiziksel_yol);
            }

            // Veritabanından kaydı sil
            $stmt_delete = $db->prepare("DELETE FROM urun_resimleri WHERE id = ?");
            $stmt_delete->execute([$resim_id]);

            sistem_log_ekle($db, 'sil', 'urun_resimleri', $resim_id, $sirket_id, ['urun_id' => $resim['urun_id'], 'resim_yolu' => $resim['resim_yolu']], 'Ürün resmi silindi.');

            return true;
        }
        return false;
    } catch (PDOException $e) {
        error_log("Ürün resmi silinirken hata oluştu: " . $e->getMessage());
        return false;
    }
}

/**
 * Bir ürün resmini varsayılan olarak ayarlar
 */
function urunResmiVarsayilanYap(PDO $db, int $urun_id, int $resim_id, int $sirket_id): bool {
    try {
        $db->beginTransaction();

        // 1. Bu ürüne ve şirkete ait diğer tüm resimlerin 'varsayilan' durumunu sıfırla
        $stmt_reset = $db->prepare("UPDATE urun_resimleri SET varsayilan = 0 WHERE urun_id = ? AND sirket_id = ?");
        $stmt_reset->execute([$urun_id, $sirket_id]);

        // 2. Seçilen resmi varsayılan olarak ayarla (şirket ID'si ile birlikte kontrol et)
        $stmt_set = $db->prepare("UPDATE urun_resimleri SET varsayilan = 1 WHERE id = ? AND urun_id = ? AND sirket_id = ?");
        $stmt_set->execute([$resim_id, $urun_id, $sirket_id]);

        $db->commit();
        return true;
    } catch (PDOException $e) {
        $db->rollBack();
        error_log("Resmi varsayılan yapma hatası: " . $e->getMessage());
        return false;
    }
}

// ============================================================================
// DEPO VE RAF YÖNETİMİ FONKSİYONLARI
// ============================================================================

/**
 * Aktif şirkete ait depoları getirir
 */
function depoGetir(PDO $db, int $sirket_id): array {
    try {
        $stmt = $db->prepare("SELECT id, depo_adi, aciklama FROM depolar WHERE sirket_id = ? AND aktif = 1 ORDER BY depo_adi");
        $stmt->execute([$sirket_id]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Depo listesi getirme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Aktif şirkete ait rafları getirir
 */
function rafGetir(PDO $db, int $sirket_id): array {
    try {
        $stmt = $db->prepare("SELECT id, raf_adi, aciklama FROM raflar WHERE sirket_id = ? AND aktif = 1 ORDER BY raf_adi");
        $stmt->execute([$sirket_id]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Raf listesi getirme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Ürün için depo/raf ataması ekler veya günceller
 */
function urunDepoRafEkle(PDO $db, int $urun_id, ?int $depo_id, ?int $raf_id, float $miktar, int $sirket_id): bool {
    try {
        // Eğer depo veya raf seçilmemişse işlem yapma
        if ($depo_id === null && $raf_id === null) {
            return true;
        }

        // Aynı ürün, depo ve raf kombinasyonu var mı kontrol et
        $stmt_check = $db->prepare("
            SELECT id, miktar FROM urun_depo_raf 
            WHERE urun_id = ? AND sirket_id = ? 
            AND (depo_id = ? OR (depo_id IS NULL AND ? IS NULL))
            AND (raf_id = ? OR (raf_id IS NULL AND ? IS NULL))
        ");
        $stmt_check->execute([$urun_id, $sirket_id, $depo_id, $depo_id, $raf_id, $raf_id]);
        $mevcut = $stmt_check->fetch(PDO::FETCH_ASSOC);

        if ($mevcut) {
            // Güncelle
            $yeni_miktar = $mevcut['miktar'] + $miktar;
            $stmt_update = $db->prepare("UPDATE urun_depo_raf SET miktar = ? WHERE id = ?");
            $stmt_update->execute([$yeni_miktar, $mevcut['id']]);
        } else {
            // Yeni kayıt ekle
            $stmt_insert = $db->prepare("
                INSERT INTO urun_depo_raf (urun_id, sirket_id, depo_id, raf_id, miktar) 
                VALUES (?, ?, ?, ?, ?)
            ");
            $stmt_insert->execute([$urun_id, $sirket_id, $depo_id, $raf_id, $miktar]);
        }

        return true;
    } catch (PDOException $e) {
        error_log("Ürün depo/raf ekleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Ürün depo/raf stok miktarını günceller
 */
function urunDepoRafGuncelle(PDO $db, int $urun_id, ?int $depo_id, ?int $raf_id, float $miktar_degisim, int $sirket_id): bool {
    try {
        // Mevcut kaydı bul
        $stmt_check = $db->prepare("
            SELECT id, miktar FROM urun_depo_raf 
            WHERE urun_id = ? AND sirket_id = ? 
            AND (depo_id = ? OR (depo_id IS NULL AND ? IS NULL))
            AND (raf_id = ? OR (raf_id IS NULL AND ? IS NULL))
        ");
        $stmt_check->execute([$urun_id, $sirket_id, $depo_id, $depo_id, $raf_id, $raf_id]);
        $mevcut = $stmt_check->fetch(PDO::FETCH_ASSOC);

        if ($mevcut) {
            $yeni_miktar = $mevcut['miktar'] + $miktar_degisim;
            
            // Negatif stok kontrolü
            if ($yeni_miktar < 0) {
                error_log("Uyarı: Depo/Raf stok miktarı negatif olamaz. Ürün ID: $urun_id");
                return false;
            }

            $stmt_update = $db->prepare("UPDATE urun_depo_raf SET miktar = ? WHERE id = ?");
            $stmt_update->execute([$yeni_miktar, $mevcut['id']]);
            return true;
        } else {
            // Kayıt yoksa ve ekleme yapılıyorsa (pozitif değişim)
            if ($miktar_degisim > 0) {
                return urunDepoRafEkle($db, $urun_id, $depo_id, $raf_id, $miktar_degisim, $sirket_id);
            }
            return false;
        }
    } catch (PDOException $e) {
        error_log("Ürün depo/raf güncelleme hatası: " . $e->getMessage());
        return false;
    }
}

/**
 * Ürünün depo/raf stok dağılımını getirir
 */
function depoRafStokGetir(PDO $db, int $urun_id, int $sirket_id): array {
    try {
        $stmt = $db->prepare("
            SELECT 
                udr.id,
                udr.depo_id,
                udr.raf_id,
                udr.miktar,
                d.depo_adi,
                r.raf_adi
            FROM urun_depo_raf udr
            LEFT JOIN depolar d ON udr.depo_id = d.id
            LEFT JOIN raflar r ON udr.raf_id = r.id
            WHERE udr.urun_id = ? AND udr.sirket_id = ?
            ORDER BY d.depo_adi, r.raf_adi
        ");
        $stmt->execute([$urun_id, $sirket_id]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Depo/Raf stok dağılımı getirme hatası: " . $e->getMessage());
        return [];
    }
}

/**
 * Depo yönetimi modülünün aktif olup olmadığını kontrol eder
 */
function depoYonetimiAktifMi(PDO $db, int $sirket_id): bool {
    try {
        $stmt = $db->prepare("SELECT depo_yonetimi_aktif FROM sirketler WHERE id = ?");
        $stmt->execute([$sirket_id]);
        $result = $stmt->fetchColumn();
        return $result == '1';
    } catch (PDOException $e) {
        error_log("Depo yönetimi modül kontrolü hatası: " . $e->getMessage());
        return false;
    }
}


