<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Carbon;

class TrimInactiveProfileLogs extends Command
{
    protected $signature = 'profiles:trim-logs {--days=30 : Number of days of logs to keep}';

    protected $description = 'Trim inactive profile log files to retain only recent entries';

    protected $logFiles = [
        'inactive-profiles.log',
        'mark-inactive-profiles.log',
    ];

    public function handle()
    {
        $daysToKeep = (int) $this->option('days');
        $cutoffDate = Carbon::now()->subDays($daysToKeep);

        $this->info("Trimming log files older than {$daysToKeep} days ({$cutoffDate->format('Y-m-d H:i:s')})...");

        $totalSizeBefore = 0;
        $totalSizeAfter = 0;
        $filesProcessed = 0;

        foreach ($this->logFiles as $logFileName) {
            $logPath = storage_path('logs/' . $logFileName);

            if (!File::exists($logPath)) {
                $this->warn("Log file not found: {$logFileName}");
                continue;
            }

            $sizeBefore = File::size($logPath);
            $totalSizeBefore += $sizeBefore;

            $trimmed = $this->trimLogFile($logPath, $cutoffDate);

            $sizeAfter = File::size($logPath);
            $totalSizeAfter += $sizeAfter;
            $filesProcessed++;

            if ($trimmed) {
                $savedBytes = $sizeBefore - $sizeAfter;
                $savedKB = round($savedBytes / 1024, 2);
                $this->info("✓ {$logFileName}: Trimmed from " . $this->formatFileSize($sizeBefore) . " to " . $this->formatFileSize($sizeAfter) . " (saved {$savedKB} KB)");
            } else {
                $this->info("✓ {$logFileName}: No entries older than {$daysToKeep} days (size: " . $this->formatFileSize($sizeBefore) . ")");
            }
        }

        if ($filesProcessed > 0) {
            $totalSaved = $totalSizeBefore - $totalSizeAfter;
            $this->info("\nTotal: Processed {$filesProcessed} files, saved " . $this->formatFileSize($totalSaved));
        }

        return 0;
    }

    /**
     * Trim log file to keep only entries newer than cutoff date.
     *
     * @param string $logPath
     * @param Carbon $cutoffDate
     * @return bool Whether any entries were removed
     */
    protected function trimLogFile($logPath, $cutoffDate)
    {
        $content = File::get($logPath);
        $lines = explode("\n", $content);
        $keptLines = [];
        $removedCount = 0;

        foreach ($lines as $line) {
            // Skip empty lines
            if (trim($line) === '') {
                continue;
            }

            // Extract timestamp from log line format: [YYYY-MM-DD HH:MM:SS] message
            if (preg_match('/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/', $line, $matches)) {
                $logDate = Carbon::parse($matches[1]);

                if ($logDate->greaterThanOrEqualTo($cutoffDate)) {
                    $keptLines[] = $line;
                } else {
                    $removedCount++;
                }
            } else {
                // Keep lines without timestamps (shouldn't happen, but be safe)
                $keptLines[] = $line;
            }
        }

        if ($removedCount > 0) {
            // Rewrite the log file with only kept lines
            File::put($logPath, implode("\n", $keptLines) . "\n");
            return true;
        }

        return false;
    }

    /**
     * Format file size in human-readable format.
     *
     * @param int $bytes
     * @return string
     */
    protected function formatFileSize($bytes)
    {
        if ($bytes >= 1048576) {
            return round($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            return round($bytes / 1024, 2) . ' KB';
        } else {
            return $bytes . ' bytes';
        }
    }
}
