<?php

namespace App\Services\Ticket;

use App\Models\Setting;
use App\Models\Ticket;
use App\Models\TicketOriginalEmail;
use App\Models\TicketReply;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

/**
 * PRC-683 Katman-2 — ham .eml (tam header dahil) retention.
 *
 * Yol: tickets/{yyyy-mm-dd}/eml/{ticket_id}/{uuid}.eml (private disk).
 * yyyy-mm-dd kronolojik=string sıralandığı için retention prune tek
 * `date_folder < cutoff` ile çalışır.
 *
 * ticket_store_original_eml=false iken hiçbir .eml yazılmaz (admin karar verir).
 */
class TicketEmlRetentionService
{
    /**
     * Ham .eml gövdesini sakla + metadata kaydı oluştur + ClamAV taramasını
     * kuyruğa al. Ayar kapalıysa no-op (null döner).
     */
    public function store(Ticket $ticket, string $rawEml, ?TicketReply $reply = null, ?string $fromEmail = null, ?string $subject = null): ?TicketOriginalEmail
    {
        if (! Setting::get('ticket_store_original_eml', false)) {
            return null;
        }

        if (trim($rawEml) === '') {
            return null;
        }

        $dateFolder = now()->format('Y-m-d');
        $uuid = (string) Str::uuid();
        $path = "tickets/{$dateFolder}/eml/{$ticket->id}/{$uuid}.eml";

        Storage::disk('private')->put($path, $rawEml);

        $record = TicketOriginalEmail::create([
            'ticket_id' => $ticket->id,
            'reply_id' => $reply?->id,
            'file_path' => $path,
            'uuid' => $uuid,
            'from_email' => $fromEmail ? Str::limit($fromEmail, 255, '') : null,
            'subject' => $subject ? Str::limit($subject, 500, '') : null,
            'file_size' => strlen($rawEml),
            'scan_status' => null,
            'date_folder' => $dateFolder,
            'pruned' => false,
        ]);

        // ClamAV taraması (PRC-334 altyapısı) — async.
        \App\Jobs\ScanTicketEmlJob::dispatch($record->id);

        Log::info('Email pipe: Original .eml stored', [
            'ticket_id' => $ticket->id,
            'eml_id' => $record->id,
            'size' => $record->file_size,
        ]);

        return $record;
    }

    /**
     * ticket_eml_retention_days'i geçen .eml dosyalarını sil + mezar-taşı notu.
     * 0 = süresiz (hiç silinmez). Silinen dosya sayısını döndürür.
     */
    public function prune(): int
    {
        $days = (int) Setting::get('ticket_eml_retention_days', 0);
        if ($days <= 0) {
            return 0; // süresiz saklama
        }

        $cutoff = now()->subDays($days)->format('Y-m-d');
        $disk = Storage::disk('private');
        $pruned = 0;

        TicketOriginalEmail::where('pruned', false)
            ->where('date_folder', '<', $cutoff)
            ->chunkById(200, function ($records) use ($disk, &$pruned) {
                foreach ($records as $record) {
                    if ($disk->exists($record->file_path)) {
                        $disk->delete($record->file_path);
                    }

                    $record->update([
                        'pruned' => true,
                        'pruned_at' => now(),
                    ]);

                    // Ticket'a mezar-taşı notu (dahili log).
                    Log::info('Email pipe: .eml pruned (retention expired)', [
                        'ticket_id' => $record->ticket_id,
                        'eml_id' => $record->id,
                        'date_folder' => $record->date_folder,
                    ]);

                    $this->leaveTombstone($record);
                    $pruned++;
                }
            });

        return $pruned;
    }

    /**
     * Silinen .eml için ticket'a küçük mezar-taşı iç notu bırak (dahili reply).
     * Markdown içerik korunur; sadece ağır forensic kopya gider.
     */
    private function leaveTombstone(TicketOriginalEmail $record): void
    {
        $ticket = $record->ticket;
        if (! $ticket) {
            return;
        }

        $note = __('admin/tickets.eml_tombstone_note', [
            'date' => $record->created_at?->format('Y-m-d') ?? $record->date_folder,
        ]);

        TicketReply::create([
            'ticket_id' => $ticket->id,
            'mail' => 'system',
            'message' => $note,
            'content_format' => 'plain',
            'is_internal' => true,
        ]);
    }
}
