<?php

namespace App\Services\Compliance;

use App\Models\CheckoutSession;
use App\Models\Event;
use App\Models\EventJoinToken;
use App\Models\EventMediaAsset;
use App\Models\EventMember;
use App\Models\PackagePurchase;
use App\Models\Photo;
use App\Models\Tenant;
use App\Models\TenantPackage;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class AccountAnonymizer
{
    public function anonymize(User $user): void
    {
        DB::transaction(function () use ($user) {
            $tenant = $user->tenant;

            if ($tenant) {
                $this->purgeTenantMedia($tenant);
                $this->scrubTenantData($tenant);
            }

            $this->scrubUser($user);
        });
    }

    public function anonymizeTenantOnly(Tenant $tenant): void
    {
        DB::transaction(function () use ($tenant) {
            $this->purgeTenantMedia($tenant);
            $this->scrubTenantData($tenant);
        });
    }

    protected function purgeTenantMedia(Tenant $tenant): void
    {
        EventMediaAsset::query()
            ->whereHas('event', fn ($query) => $query->where('tenant_id', $tenant->id))
            ->chunkById(100, function ($assets) {
                foreach ($assets as $asset) {
                    if ($asset->disk && $asset->path) {
                        Storage::disk($asset->disk)->delete($asset->path);
                    }

                    $asset->delete();
                }
            });

        Photo::query()
            ->where(function ($query) use ($tenant) {
                $query->where('tenant_id', $tenant->id)
                    ->orWhereHas('event', fn ($inner) => $inner->where('tenant_id', $tenant->id));
            })
            ->chunkById(200, function ($photos) {
                foreach ($photos as $photo) {
                    $photo->delete();
                }
            });
    }

    protected function scrubTenantData(Tenant $tenant): void
    {
        $eventIds = Event::query()
            ->where('tenant_id', $tenant->id)
            ->pluck('id');

        EventJoinToken::query()->whereIn('event_id', $eventIds)->delete();
        EventMember::query()->where('tenant_id', $tenant->id)->delete();

        Event::query()
            ->whereIn('id', $eventIds)
            ->chunkById(100, function ($events) {
                foreach ($events as $event) {
                    $event->forceFill([
                        'name' => ['de' => 'Anonymisiertes Event', 'en' => 'Anonymized Event'],
                        'description' => null,
                        'location' => null,
                        'slug' => 'anonymized-event-'.$event->id,
                        'status' => 'archived',
                    ])->save();

                    $event->loadMissing('photoboothSetting');

                    if ($event->photoboothSetting) {
                        $event->photoboothSetting->forceFill([
                            'enabled' => false,
                            'status' => 'inactive',
                            'username' => null,
                            'password' => null,
                            'path' => null,
                            'expires_at' => null,
                            'last_deprovisioned_at' => now(),
                            'last_upload_at' => null,
                            'uploads_last_24h' => 0,
                            'uploads_total' => 0,
                        ])->save();
                    }
                }
            });

        PackagePurchase::query()
            ->where('tenant_id', $tenant->id)
            ->update([
                'ip_address' => null,
                'user_agent' => null,
            ]);

        CheckoutSession::query()
            ->where('tenant_id', $tenant->id)
            ->update([
                'tenant_id' => null,
                'user_id' => null,
                'provider_metadata' => [],
            ]);

        TenantPackage::query()
            ->where('tenant_id', $tenant->id)
            ->update(['active' => false]);

        $tenant->forceFill([
            'name' => 'Anonymisierter Tenant #'.$tenant->id,
            'slug' => 'anonymized-tenant-'.$tenant->id,
            'contact_name' => null,
            'contact_email' => null,
            'contact_phone' => null,
            'email' => null,
            'domain' => null,
            'custom_domain' => null,
            'user_id' => null,
            'anonymized_at' => now(),
            'pending_deletion_at' => null,
            'deletion_warning_sent_at' => null,
            'subscription_status' => 'deleted',
            'is_active' => 0,
            'is_suspended' => 1,
        ])->save();
    }

    protected function scrubUser(User $user): void
    {
        $placeholderEmail = sprintf('deleted+%s@fotospiel.app', $user->id);

        $user->forceFill([
            'name' => 'Anonymisierter Benutzer',
            'email' => $placeholderEmail,
            'username' => null,
            'first_name' => null,
            'last_name' => null,
            'address' => null,
            'phone' => null,
            'password' => Str::random(40),
            'remember_token' => null,
            'pending_purchase' => false,
            'email_verified_at' => null,
            'role' => 'user',
        ])->save();
    }
}
