<?php

namespace App\Console\Commands;

use App\Jobs\AnonymizeAccount;
use App\Models\Tenant;
use App\Notifications\InactiveTenantDeletionWarning;
use App\Services\Compliance\RetentionOverrideService;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Notification;

class ProcessTenantRetention extends Command
{
    protected $signature = 'tenants:retention-scan';

    protected $description = 'Scans tenants for Inaktivität, verschickt Warnungen und startet Anonymisierungen.';

    public function handle(): int
    {
        $warningThreshold = now()->subMonths(23);
        $deletionThreshold = now()->subMonths(24);

        Tenant::query()
            ->whereNull('anonymized_at')
            ->with(['user'])
            ->withMax('events as last_event_activity', 'updated_at')
            ->withMax('purchases as last_purchase_activity', 'purchased_at')
            ->withMax('photos as last_photo_activity', 'created_at')
            ->chunkById(100, function ($tenants) use ($warningThreshold, $deletionThreshold) {
                $overrides = app(RetentionOverrideService::class);

                foreach ($tenants as $tenant) {
                    if ($overrides->tenantOnHold($tenant)) {
                        continue;
                    }

                    $lastActivity = $this->determineLastActivity($tenant);

                    if (! $lastActivity) {
                        $lastActivity = $tenant->created_at ?? now();
                    }

                    if ($this->hasActiveSubscription($tenant)) {
                        continue;
                    }

                    if ($lastActivity->lte($deletionThreshold)) {
                        $this->dispatchAnonymization($tenant);

                        continue;
                    }

                    if ($lastActivity->lte($warningThreshold) && $tenant->deletion_warning_sent_at === null) {
                        $this->sendWarning($tenant, $lastActivity->copy()->addMonths(24));
                    }
                }
            });

        $this->info(__('profile.retention.scan_complete'));

        return self::SUCCESS;
    }

    protected function determineLastActivity(Tenant $tenant): ?Carbon
    {
        $candidates = collect([
            $tenant->last_activity_at,
            $tenant->last_event_activity ? Carbon::parse($tenant->last_event_activity) : null,
            $tenant->last_purchase_activity ? Carbon::parse($tenant->last_purchase_activity) : null,
            $tenant->last_photo_activity ? Carbon::parse($tenant->last_photo_activity) : null,
        ])->filter();

        if ($candidates->isEmpty()) {
            return $tenant->created_at ? $tenant->created_at->copy() : null;
        }

        return $candidates->sort()->last();
    }

    protected function hasActiveSubscription(Tenant $tenant): bool
    {
        return $tenant->tenantPackages()
            ->where('active', true)
            ->whereHas('package', fn ($query) => $query->where('type', 'reseller'))
            ->exists();
    }

    protected function sendWarning(Tenant $tenant, Carbon $plannedDeletion): void
    {
        $email = $tenant->contact_email
            ?? $tenant->email
            ?? $tenant->user?->email;

        if (! $email) {
            return;
        }

        Notification::route('mail', $email)
            ->notify(new InactiveTenantDeletionWarning($tenant, $plannedDeletion));

        $tenant->forceFill([
            'deletion_warning_sent_at' => now(),
            'pending_deletion_at' => $plannedDeletion,
        ])->save();
    }

    protected function dispatchAnonymization(Tenant $tenant): void
    {
        if ($tenant->anonymized_at) {
            return;
        }

        AnonymizeAccount::dispatch($tenant->user?->id, $tenant->id);
    }
}
