<?php

namespace App\Services;

use App\Models\ActivityLog;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ActivityLogService
{
    /**
     * Log an activity.
     */
    public function log(
        string $action,
        ?string $description = null,
        ?Model $model = null,
        ?array $properties = null,
        ?Request $request = null
    ): ActivityLog {
        $user = Auth::user();
        $request = $request ?? request();

        $data = [
            'user_id' => $user?->id,
            'action' => $action,
            'description' => $description,
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'method' => $request->method(),
            'url' => $request->fullUrl(),
        ];

        if ($model) {
            $data['model_type'] = get_class($model);
            $data['model_id'] = $model->id;
        }

        if ($properties) {
            $data['properties'] = $properties;
        }

        return ActivityLog::create($data);
    }

    /**
     * Log a login activity.
     */
    public function logLogin(?Request $request = null): ActivityLog
    {
        $user = Auth::user();
        $request = $request ?? request();

        return $this->log(
            action: 'login',
            description: "User {$user?->name} ({$user?->email}) logged in",
            properties: [
                'email' => $user?->email,
                'role' => $user?->role?->value,
            ],
            request: $request
        );
    }

    /**
     * Log a logout activity.
     */
    public function logLogout(?Request $request = null): ActivityLog
    {
        $user = Auth::user();
        $request = $request ?? request();

        return $this->log(
            action: 'logout',
            description: "User {$user?->name} ({$user?->email}) logged out",
            properties: [
                'email' => $user?->email,
                'role' => $user?->role?->value,
            ],
            request: $request
        );
    }

    /**
     * Log a create activity.
     */
    public function logCreate(Model $model, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Created {$modelName} #{$model->id}";

        return $this->log(
            action: 'create',
            description: $description,
            model: $model,
            properties: $properties
        );
    }

    /**
     * Log an update activity.
     */
    public function logUpdate(Model $model, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Updated {$modelName} #{$model->id}";

        return $this->log(
            action: 'update',
            description: $description,
            model: $model,
            properties: $properties
        );
    }

    /**
     * Log a delete activity.
     */
    public function logDelete(Model $model, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Deleted {$modelName} #{$model->id}";

        // Store model data before deletion
        $modelData = $model->toArray();

        return $this->log(
            action: 'delete',
            description: $description,
            model: $model,
            properties: array_merge($properties ?? [], ['deleted_data' => $modelData])
        );
    }

    /**
     * Log a view activity.
     */
    public function logView(Model $model, ?string $description = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Viewed {$modelName} #{$model->id}";

        return $this->log(
            action: 'view',
            description: $description,
            model: $model
        );
    }

    /**
     * Log a registration activity.
     */
    public function logRegistration(User $user, ?Request $request = null): ActivityLog
    {
        return $this->log(
            action: 'registration',
            description: "User {$user->name} ({$user->email}) registered",
            model: $user,
            properties: [
                'email' => $user->email,
                'name' => $user->name,
                'role' => $user->role?->value,
            ],
            request: $request
        );
    }

    /**
     * Log an OTP verification activity.
     */
    public function logOtpVerification(User $user, ?Request $request = null): ActivityLog
    {
        return $this->log(
            action: 'otp_verification',
            description: "User {$user->name} ({$user->email}) verified email with OTP",
            model: $user,
            properties: [
                'email' => $user->email,
            ],
            request: $request
        );
    }

    /**
     * Log a password reset request activity.
     */
    public function logPasswordResetRequest(string $email, ?Request $request = null): ActivityLog
    {
        return $this->log(
            action: 'password_reset_request',
            description: "Password reset requested for email: {$email}",
            properties: [
                'email' => $email,
            ],
            request: $request
        );
    }

    /**
     * Log a password reset activity.
     */
    public function logPasswordReset(User $user, ?Request $request = null): ActivityLog
    {
        return $this->log(
            action: 'password_reset',
            description: "User {$user->name} ({$user->email}) reset their password",
            model: $user,
            properties: [
                'email' => $user->email,
            ],
            request: $request
        );
    }

    /**
     * Log a topup coin activity.
     */
    public function logTopupCoin(Model $transaction, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $description = $description ?? "Topup coin transaction #{$transaction->id}";

        return $this->log(
            action: 'topup_coin',
            description: $description,
            model: $transaction,
            properties: $properties
        );
    }

    /**
     * Log a payment success activity.
     */
    public function logPaymentSuccess(Model $transaction, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $description = $description ?? "Payment successful for transaction #{$transaction->id}";

        return $this->log(
            action: 'payment_success',
            description: $description,
            model: $transaction,
            properties: $properties
        );
    }

    /**
     * Log a settings update activity.
     */
    public function logSettingsUpdate(?string $description = null, ?array $properties = null, ?Request $request = null): ActivityLog
    {
        $description = $description ?? 'Updated settings';

        return $this->log(
            action: 'settings_update',
            description: $description,
            properties: $properties,
            request: $request
        );
    }

    /**
     * Log a purchase/show purchase activity.
     */
    public function logPurchase(Model $model, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Purchased {$modelName} #{$model->id}";

        return $this->log(
            action: 'purchase',
            description: $description,
            model: $model,
            properties: $properties
        );
    }

    /**
     * Log a watch/view streaming activity.
     */
    public function logWatch(Model $model, ?string $description = null, ?array $properties = null): ActivityLog
    {
        $modelName = class_basename($model);
        $description = $description ?? "Watched {$modelName} #{$model->id}";

        return $this->log(
            action: 'watch',
            description: $description,
            model: $model,
            properties: $properties
        );
    }
}
