<?php

namespace Modules\SmartStorage\Entities\Services;

use Illuminate\Support\Str;
use Modules\SmartStorage\Entities\SsAccessLog;
use Modules\SmartStorage\Entities\SsFile;
use Modules\SmartStorage\Entities\SsSetting;

/**
 * Central writer for ss_access_logs — every write/read/delete and every denial
 * funnels through here so the audit trail is complete and consistent. Logging is
 * best-effort: a logging failure must never break a file operation.
 */
class AccessLogger
{
    public function __construct(protected GeoResolver $geo, protected DeviceManager $devices)
    {
    }

    public function log(string $action, bool $granted, ?string $reason, ?SsFile $file, ?string $logicalPath = null): void
    {
        try {
            $settings = SsSetting::current();
            if ($action === 'read' && !$settings->track_reads) {
                return;
            }
            if ($action === 'write' && !$settings->track_writes) {
                return;
            }

            $request = request();
            $ip = $request?->ip();
            $g = $this->geo->resolve($ip);

            SsAccessLog::create([
                'business_id'        => $settings->business_id,
                'file_id'            => $file?->id,
                'logical_path'       => $logicalPath ?? $file?->logical_path,
                'action'             => $action,
                'granted'            => $granted,
                'reason'             => $reason,
                'user_id'            => auth()->id(),
                'device_fingerprint' => $this->safeFingerprint(),
                'ip'                 => $ip,
                'user_agent'         => Str::limit((string) $request?->userAgent(), 250, ''),
                'geo_country'        => $g['country'],
                'geo_city'           => $g['city'],
                'geo_lat'            => $g['lat'],
                'geo_lng'            => $g['lng'],
                'created_at'         => now(),
            ]);
        } catch (\Throwable $e) {
            // swallow — logging must not break storage
        }
    }

    protected function safeFingerprint(): ?string
    {
        try {
            return $this->devices->fingerprintHash();
        } catch (\Throwable $e) {
            return null;
        }
    }
}
