<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Schema;

class SystemCleanupCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'system:cleanup';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Clean up temporary files, logs, and old data';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        try {
            $this->info('Starting system cleanup...');
            
            $cleanedItems = 0;
            
            // Clean up old logs (keep last 30 days)
            $cleanedItems += $this->cleanupLogs();
            
            // Clean up old failed jobs
            $cleanedItems += $this->cleanupFailedJobs();
            
            // Clean up temporary uploads
            $cleanedItems += $this->cleanupTempFiles();
            
            // Clean up old sessions
            $cleanedItems += $this->cleanupSessions();
            
            // Clean up old notifications
            $cleanedItems += $this->cleanupNotifications();

            // Update last cleanup timestamp
            DB::table('settings')
                ->updateOrInsert(
                    ['key' => 'last_system_cleanup'],
                    ['value' => now()->toISOString(), 'updated_at' => now()]
                );

            $message = "System cleanup completed. Cleaned {$cleanedItems} items";
            $this->info($message);
            Log::info($message);

            return Command::SUCCESS;
            
        } catch (\Exception $e) {
            $error = 'Error during system cleanup: ' . $e->getMessage();
            $this->error($error);
            Log::error($error);
            return Command::FAILURE;
        }
    }

    /**
     * Clean up old log files
     */
    private function cleanupLogs()
    {
        $cleaned = 0;
        
        try {
            // Clean Laravel logs older than 30 days
            $oldLogs = 0;
            
            // Check if notifications table exists for log cleanup
            if (Schema::hasTable('notifications')) {
                $oldLogs = DB::table('notifications')
                    ->where('created_at', '<', now()->subDays(30))
                    ->count();
                    
                DB::table('notifications')
                    ->where('created_at', '<', now()->subDays(30))
                    ->delete();
            }
                
            $cleaned += $oldLogs;
            $this->info("Cleaned {$oldLogs} old log entries");
            
        } catch (\Exception $e) {
            Log::warning('Failed to cleanup logs: ' . $e->getMessage());
        }
        
        return $cleaned;
    }

    /**
     * Clean up failed jobs older than 7 days
     */
    private function cleanupFailedJobs()
    {
        $cleaned = 0;
        
        try {
            $oldJobs = DB::table('failed_jobs')
                ->where('failed_at', '<', now()->subDays(7))
                ->count();
                
            DB::table('failed_jobs')
                ->where('failed_at', '<', now()->subDays(7))
                ->delete();
                
            $cleaned += $oldJobs;
            $this->info("Cleaned {$oldJobs} old failed jobs");
            
        } catch (\Exception $e) {
            Log::warning('Failed to cleanup failed jobs: ' . $e->getMessage());
        }
        
        return $cleaned;
    }

    /**
     * Clean up temporary upload files
     */
    private function cleanupTempFiles()
    {
        $cleaned = 0;
        
        try {
            $tempPath = storage_path('app/temp');
            
            if (is_dir($tempPath)) {
                $files = glob($tempPath . '/*');
                
                foreach ($files as $file) {
                    if (is_file($file) && filemtime($file) < strtotime('-1 hour')) {
                        unlink($file);
                        $cleaned++;
                    }
                }
            }
            
            $this->info("Cleaned {$cleaned} temporary files");
            
        } catch (\Exception $e) {
            Log::warning('Failed to cleanup temp files: ' . $e->getMessage());
        }
        
        return $cleaned;
    }

    /**
     * Clean up old sessions
     */
    private function cleanupSessions()
    {
        $cleaned = 0;
        
        try {
            $oldSessions = DB::table('sessions')
                ->where('last_activity', '<', now()->subDays(30)->timestamp)
                ->count();
                
            DB::table('sessions')
                ->where('last_activity', '<', now()->subDays(30)->timestamp)
                ->delete();
                
            $cleaned += $oldSessions;
            $this->info("Cleaned {$oldSessions} old sessions");
            
        } catch (\Exception $e) {
            Log::warning('Failed to cleanup sessions: ' . $e->getMessage());
        }
        
        return $cleaned;
    }

    /**
     * Clean up old notifications
     */
    private function cleanupNotifications()
    {
        $cleaned = 0;
        
        try {
            $oldNotifications = DB::table('notifications')
                ->where('created_at', '<', now()->subDays(90))
                ->count();
                
            DB::table('notifications')
                ->where('created_at', '<', now()->subDays(90))
                ->delete();
                
            $cleaned += $oldNotifications;
            $this->info("Cleaned {$oldNotifications} old notifications");
            
        } catch (\Exception $e) {
            Log::warning('Failed to cleanup notifications: ' . $e->getMessage());
        }
        
        return $cleaned;
    }
}