<?php

namespace App\Models;

use CodeIgniter\Model;

class DeletedUserModel extends Model
{
    protected $table      = 'deleted_users';
    protected $primaryKey = 'id';

    protected $useAutoIncrement = true;

    protected $returnType     = 'array';
    protected $useSoftDeletes = false;

    protected $allowedFields = [
        'original_user_id',
        'username', 
        'mail',
        'name_surname',
        'phone',
        'registration_date',
        'deletion_date',
        'deletion_ip',
        'deletion_reason',
        'user_data_json',
        'deleted_by_user',
        'deleted_by_admin_id',
        'admin_notes',
        'restore_possible',
        'restore_deadline',
        'gdpr_request_id',
        'security_log_id',
        'verification_status',
        'data_export_completed'
    ];

    // Timestamps
    protected $useTimestamps = true;
    protected $dateFormat    = 'datetime';
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';

    // Validation
    protected $validationRules = [
        'original_user_id' => 'required|integer',
        'mail' => 'required|valid_email',
        'deletion_date' => 'required',
        'deletion_ip' => 'required'
    ];

    protected $validationMessages = [
        'original_user_id' => [
            'required' => 'Orijinal kullanıcı ID gerekli',
            'integer' => 'Geçerli bir kullanıcı ID giriniz'
        ],
        'mail' => [
            'required' => 'E-posta adresi gerekli',
            'valid_email' => 'Geçerli bir e-posta adresi giriniz'
        ],
        'deletion_date' => [
            'required' => 'Silme tarihi gerekli'
        ],
        'deletion_ip' => [
            'required' => 'IP adresi gerekli'
        ]
    ];

    protected $skipValidation = false;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = ['addSecurityData'];
    protected $afterInsert    = ['logDeletionEvent'];

    /**
     * Kullanıcıyı güvenli şekilde arşivle
     */
    public function archiveUser($userData, $deletionReason = 'Kullanıcı talebi', $deletedByUserId = null, $adminId = null)
    {
        $archiveData = [
            'original_user_id' => $userData['id'],
            'username' => $userData['username'],
            'mail' => $userData['mail'],
            'name_surname' => $userData['name_surname'],
            'phone' => $userData['phone'] ?? '',
            'registration_date' => $userData['registration_date'],
            'deletion_date' => date('Y-m-d H:i:s'),
            'deletion_ip' => $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0',
            'deletion_reason' => $deletionReason,
            'user_data_json' => json_encode($userData),
            'deleted_by_user' => $deletedByUserId ? 1 : 0,
            'deleted_by_admin_id' => $adminId,
            'restore_possible' => 1,
            'restore_deadline' => date('Y-m-d H:i:s', strtotime('+30 days')),
            'admin_notes' => '',
            'verification_status' => 'verified', // Şifre doğrulandı
            'data_export_completed' => 0
        ];

        try {
            $insertId = $this->insert($archiveData);
            
            if ($insertId) {
                log_message('info', "Kullanıcı başarıyla arşivlendi - Original ID: {$userData['id']}, Archive ID: {$insertId}");
                return $insertId;
            } else {
                log_message('error', "Kullanıcı arşivlenemedi - Original ID: {$userData['id']}");
                return false;
            }
        } catch (\Exception $e) {
            log_message('error', "Kullanıcı arşivleme hatası: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Geri yüklenebilir kullanıcıları getir
     */
    public function getRestorableUsers($limit = 50, $offset = 0)
    {
        return $this->where('restore_possible', 1)
                   ->where('restore_deadline >', date('Y-m-d H:i:s'))
                   ->orderBy('deletion_date', 'DESC')
                   ->findAll($limit, $offset);
    }

    /**
     * Belirli bir kullanıcının silme geçmişini getir
     */
    public function getUserDeletionHistory($originalUserId)
    {
        return $this->where('original_user_id', $originalUserId)
                   ->orderBy('deletion_date', 'DESC')
                   ->findAll();
    }

    /**
     * E-posta adresine göre silinen kullanıcıları getir
     */
    public function getDeletedUsersByEmail($email)
    {
        return $this->where('mail', $email)
                   ->orderBy('deletion_date', 'DESC')
                   ->findAll();
    }

    /**
     * Son X gün içinde silinen kullanıcıları getir
     */
    public function getRecentlyDeletedUsers($days = 7, $limit = 100)
    {
        $dateThreshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
        
        return $this->where('deletion_date >', $dateThreshold)
                   ->orderBy('deletion_date', 'DESC')
                   ->findAll($limit);
    }

    /**
     * Süresi geçmiş arşivleri temizle
     */
    public function cleanExpiredArchives($dryRun = false)
    {
        $expiredArchives = $this->where('restore_deadline <', date('Y-m-d H:i:s'))
                               ->where('restore_possible', 1)
                               ->findAll();

        $cleanedCount = 0;

        foreach ($expiredArchives as $archive) {
            if (!$dryRun) {
                // Hassas verileri temizle ama kaydı tut
                $updateData = [
                    'user_data_json' => null, // Hassas verileri temizle
                    'restore_possible' => 0,
                    'admin_notes' => $archive['admin_notes'] . ' | Arşiv süresi doldu: ' . date('Y-m-d H:i:s'),
                    'data_export_completed' => 1
                ];
                
                $this->update($archive['id'], $updateData);
                $cleanedCount++;
                
                log_message('info', "Süresi dolmuş arşiv temizlendi - Archive ID: {$archive['id']}, Original User ID: {$archive['original_user_id']}");
            }
        }

        return [
            'found' => count($expiredArchives),
            'cleaned' => $cleanedCount,
            'dry_run' => $dryRun
        ];
    }

    /**
     * Kullanıcıyı geri yükle (restore)
     */
    public function restoreUser($archiveId, $adminId)
    {
        $archive = $this->find($archiveId);
        
        if (!$archive) {
            return ['success' => false, 'message' => 'Arşiv kaydı bulunamadı'];
        }

   if ($archive['restore_possible'] != 1) {
            return ['success' => false, 'message' => 'Bu kullanıcı geri yüklenemez'];
        }

        if (strtotime($archive['restore_deadline']) < time()) {
            return ['success' => false, 'message' => 'Geri yükleme süresi dolmuş'];
        }

        if (empty($archive['user_data_json'])) {
            return ['success' => false, 'message' => 'Kullanıcı verileri mevcut değil'];
        }

        try {
            $userData = json_decode($archive['user_data_json'], true);
            
            if (!$userData) {
                return ['success' => false, 'message' => 'Kullanıcı verileri okunamadı'];
            }

            // Kullanıcıyı yeniden oluştur
            $userModel = model('App\Models\UserModel');
            
            // E-posta çakışmasını kontrol et
            $existingUser = $userModel->where('mail', $userData['mail'])->first();
            if ($existingUser) {
                return ['success' => false, 'message' => 'Bu e-posta adresi zaten kullanımda'];
            }

            // Kullanıcıyı geri yükle
            $newUserId = $userModel->insert($userData);
            
            if ($newUserId) {
                // Arşiv kaydını güncelle
                $this->update($archiveId, [
                    'restore_possible' => 0,
                    'admin_notes' => $archive['admin_notes'] . ' | Geri yüklendi: ' . date('Y-m-d H:i:s') . ' (Admin: ' . $adminId . ')',
                    'data_export_completed' => 1
                ]);

                log_message('info', "Kullanıcı başarıyla geri yüklendi - Archive ID: {$archiveId}, New User ID: {$newUserId}, Admin: {$adminId}");

                return [
                    'success' => true, 
                    'message' => 'Kullanıcı başarıyla geri yüklendi',
                    'new_user_id' => $newUserId
                ];
            } else {
                return ['success' => false, 'message' => 'Kullanıcı geri yüklenemedi'];
            }

        } catch (\Exception $e) {
            log_message('error', "Kullanıcı geri yükleme hatası: " . $e->getMessage());
            return ['success' => false, 'message' => 'Sistem hatası: ' . $e->getMessage()];
        }
    }

    /**
     * İstatistiksel raporlama
     */
    public function getDeletionStatistics($startDate = null, $endDate = null)
    {
        $builder = $this->builder();

        if ($startDate) {
            $builder->where('deletion_date >=', $startDate);
        }

        if ($endDate) {
            $builder->where('deletion_date <=', $endDate);
        }

        $totalDeleted = $builder->countAllResults(false);

        // Sebeplere göre dağılım
        $builder->select('deletion_reason, COUNT(*) as count')
                ->groupBy('deletion_reason');
        $reasonStats = $builder->get()->getResultArray();

        // Kullanıcı vs Admin silme dağılımı
        $builder = $this->builder();
        if ($startDate) $builder->where('deletion_date >=', $startDate);
        if ($endDate) $builder->where('deletion_date <=', $endDate);
        
        $userDeleted = $builder->where('deleted_by_user', 1)->countAllResults();
        $adminDeleted = $totalDeleted - $userDeleted;

        // Aylık dağılım
        $builder = $this->builder();
        if ($startDate) $builder->where('deletion_date >=', $startDate);
        if ($endDate) $builder->where('deletion_date <=', $endDate);
        
        $builder->select('YEAR(deletion_date) as year, MONTH(deletion_date) as month, COUNT(*) as count')
                ->groupBy('YEAR(deletion_date), MONTH(deletion_date)')
                ->orderBy('year DESC, month DESC');
        $monthlyStats = $builder->get()->getResultArray();

        return [
            'total_deleted' => $totalDeleted,
            'user_deleted' => $userDeleted,
            'admin_deleted' => $adminDeleted,
            'reason_breakdown' => $reasonStats,
            'monthly_breakdown' => $monthlyStats,
            'period' => [
                'start' => $startDate,
                'end' => $endDate
            ]
        ];
    }

    /**
     * GDPR uyumluluk kontrolü
     */
    public function checkGdprCompliance()
    {
        // 30 günden eski ve hala kişisel veri içeren kayıtlar
        $nonCompliantRecords = $this->where('deletion_date <', date('Y-m-d H:i:s', strtotime('-30 days')))
                                   ->where('user_data_json IS NOT NULL')
                                   ->where('restore_possible', 1)
                                   ->findAll();

        $complianceIssues = [];

        foreach ($nonCompliantRecords as $record) {
            $complianceIssues[] = [
                'archive_id' => $record['id'],
                'original_user_id' => $record['original_user_id'],
                'email' => $record['mail'],
                'deletion_date' => $record['deletion_date'],
                'days_overdue' => floor((time() - strtotime($record['deletion_date'])) / (24 * 60 * 60)) - 30,
                'issue' => 'Kişisel veriler 30 günden uzun süredir saklanıyor'
            ];
        }

        return [
            'compliant' => empty($complianceIssues),
            'total_issues' => count($complianceIssues),
            'issues' => $complianceIssues
        ];
    }

    /**
     * Veri dışa aktarma işaretleme
     */
    public function markDataExportCompleted($archiveId, $exportPath = null)
    {
        $updateData = [
            'data_export_completed' => 1,
            'admin_notes' => $this->find($archiveId)['admin_notes'] . ' | Veri dışa aktarıldı: ' . date('Y-m-d H:i:s')
        ];

        if ($exportPath) {
            $updateData['admin_notes'] .= ' (Dosya: ' . $exportPath . ')';
        }

        return $this->update($archiveId, $updateData);
    }

    /**
     * Güvenlik verileri ekleme (callback)
     */
    protected function addSecurityData(array $data)
    {
        if (isset($data['data'])) {
            $data['data']['security_log_id'] = $this->generateSecurityLogId();
            $data['data']['verification_status'] = $data['data']['verification_status'] ?? 'pending';
        }

        return $data;
    }

    /**
     * Silme olayını loglama (callback)
     */
    protected function logDeletionEvent(array $data)
    {
        if (isset($data['id']) && isset($data['data'])) {
            $logData = $data['data'];
            log_message('info', "Kullanıcı silme arşivi oluşturuldu - Archive ID: {$data['id']}, Original User: {$logData['original_user_id']} ({$logData['mail']})");
        }

        return $data;
    }

    /**
     * Güvenlik log ID'si oluştur
     */
    private function generateSecurityLogId()
    {
        return 'DEL_' . date('Ymd_His') . '_' . rand(1000, 9999);
    }

    /**
     * Bulk işlemler için optimize edilmiş silme
     */
    public function bulkArchiveUsers(array $userIds, $deletionReason = 'Bulk deletion', $adminId = null)
    {
        $userModel = model('App\Models\UserModel');
        $successCount = 0;
        $errors = [];

        foreach ($userIds as $userId) {
            try {
                $user = $userModel->find($userId);
                
                if (!$user) {
                    $errors[] = "Kullanıcı bulunamadı: $userId";
                    continue;
                }

                $result = $this->archiveUser($user, $deletionReason, null, $adminId);
                
                if ($result) {
                    $successCount++;
                } else {
                    $errors[] = "Arşivlenemedi: $userId";
                }

            } catch (\Exception $e) {
                $errors[] = "Hata (User $userId): " . $e->getMessage();
            }
        }

        return [
            'total_requested' => count($userIds),
            'successful' => $successCount,
            'failed' => count($errors),
            'errors' => $errors
        ];
    }

    /**
     * Arama ve filtreleme
     */
    public function searchDeletedUsers($filters = [])
    {
        $builder = $this->builder();

        // E-posta filtresi
        if (!empty($filters['email'])) {
            $builder->like('mail', $filters['email']);
        }

        // İsim filtresi
        if (!empty($filters['name'])) {
            $builder->like('name_surname', $filters['name']);
        }

        // Tarih aralığı filtresi
        if (!empty($filters['date_from'])) {
            $builder->where('deletion_date >=', $filters['date_from']);
        }

        if (!empty($filters['date_to'])) {
            $builder->where('deletion_date <=', $filters['date_to']);
        }

        // Silme sebebi filtresi
        if (!empty($filters['reason'])) {
            $builder->like('deletion_reason', $filters['reason']);
        }

        // Silme türü filtresi (kullanıcı/admin)
        if (isset($filters['deleted_by_user'])) {
            $builder->where('deleted_by_user', $filters['deleted_by_user']);
        }

        // Geri yüklenebilirlik filtresi
        if (isset($filters['restorable'])) {
            if ($filters['restorable']) {
                $builder->where('restore_possible', 1)
                        ->where('restore_deadline >', date('Y-m-d H:i:s'));
            } else {
                $builder->groupStart()
                        ->where('restore_possible', 0)
                        ->orWhere('restore_deadline <=', date('Y-m-d H:i:s'))
                        ->groupEnd();
            }
        }

        // Sıralama
        $orderBy = $filters['order_by'] ?? 'deletion_date';
        $orderDir = $filters['order_dir'] ?? 'DESC';
        $builder->orderBy($orderBy, $orderDir);

        // Sayfalama
        $limit = $filters['limit'] ?? 50;
        $offset = $filters['offset'] ?? 0;

        return $builder->findAll($limit, $offset);
    }

    /**
     * Arama sonuçlarının toplam sayısını getir
     */
    public function getSearchCount($filters = [])
    {
        $builder = $this->builder();

        if (!empty($filters['email'])) {
            $builder->like('mail', $filters['email']);
        }

        if (!empty($filters['name'])) {
            $builder->like('name_surname', $filters['name']);
        }

        if (!empty($filters['date_from'])) {
            $builder->where('deletion_date >=', $filters['date_from']);
        }

        if (!empty($filters['date_to'])) {
            $builder->where('deletion_date <=', $filters['date_to']);
        }

        if (!empty($filters['reason'])) {
            $builder->like('deletion_reason', $filters['reason']);
        }

        if (isset($filters['deleted_by_user'])) {
            $builder->where('deleted_by_user', $filters['deleted_by_user']);
        }

        if (isset($filters['restorable'])) {
            if ($filters['restorable']) {
                $builder->where('restore_possible', 1)
                        ->where('restore_deadline >', date('Y-m-d H:i:s'));
            } else {
                $builder->groupStart()
                        ->where('restore_possible', 0)
                        ->orWhere('restore_deadline <=', date('Y-m-d H:i:s'))
                        ->groupEnd();
            }
        }

        return $builder->countAllResults();
    }

    /**
     * Veri temizliği için güvenli silme
     */
    public function permanentlyDeleteArchive($archiveId, $adminId, $reason = 'Manual cleanup')
    {
        $archive = $this->find($archiveId);
        
        if (!$archive) {
            return ['success' => false, 'message' => 'Arşiv kaydı bulunamadı'];
        }

        try {
            // Önce admin notlarını güncelle
            $finalNotes = $archive['admin_notes'] . " | Kalıcı silme: " . date('Y-m-d H:i:s') . " (Admin: $adminId, Sebep: $reason)";
            
            $this->update($archiveId, [
                'user_data_json' => null,
                'admin_notes' => $finalNotes,
                'restore_possible' => 0,
                'data_export_completed' => 1
            ]);

            log_message('info', "Arşiv kaydı kalıcı olarak temizlendi - Archive ID: $archiveId, Admin: $adminId");

            return [
                'success' => true,
                'message' => 'Arşiv kaydı kalıcı olarak temizlendi'
            ];

        } catch (\Exception $e) {
            log_message('error', "Arşiv kalıcı silme hatası: " . $e->getMessage());
            return ['success' => false, 'message' => 'Sistem hatası: ' . $e->getMessage()];
        }
    }

    /**
     * Otomatik temizlik için cron job
     */
    public function autoCleanup()
    {
        // 1. Süresi dolmuş arşivleri temizle
        $cleanupResult = $this->cleanExpiredArchives();

        // 2. GDPR uyumluluk kontrolü
        $complianceCheck = $this->checkGdprCompliance();

        // 3. Çok eski kayıtları kalıcı temizle (1 yıldan eski)
        $veryOldRecords = $this->where('deletion_date <', date('Y-m-d H:i:s', strtotime('-1 year')))
                              ->where('user_data_json IS NOT NULL')
                              ->findAll();

        $permanentlyDeleted = 0;
        foreach ($veryOldRecords as $record) {
            $result = $this->permanentlyDeleteArchive($record['id'], 0, 'Auto cleanup - 1 year old');
            if ($result['success']) {
                $permanentlyDeleted++;
            }
        }

        return [
            'expired_cleanup' => $cleanupResult,
            'gdpr_compliance' => $complianceCheck,
            'permanently_deleted' => $permanentlyDeleted,
            'cleanup_date' => date('Y-m-d H:i:s')
        ];
    }
}