<?php

namespace App\Services\MicrosoftGraph;

use App\Models\MsgraphPendingChange;
use App\Models\User;
use Illuminate\Support\Collection;

/**
 * Service for managing Microsoft Graph pending changes
 */
class MsgraphPendingChangeService
{
    /**
     * Create a user membership change record
     */
    public function createUserMembershipChange(
        $model,
        string $action,
        int $userId,
        string $oldType = null,
        string $newType = null,
        array $metadata = []
    ): MsgraphPendingChange {
        return MsgraphPendingChange::create([
            'model_type' => get_class($model),
            'model_id' => $model->id,
            'action' => $action,
            'user_id' => $userId,
            'old_membership_type' => $oldType,
            'new_membership_type' => $newType,
            'metadata' => $metadata,
            'priority' => 'normal'
        ]);
    }

    /**
     * Get unprocessed changes for a specific model
     */
    public function getPendingChangesForModel($model): Collection
    {
        return MsgraphPendingChange::where('model_type', get_class($model))
            ->where('model_id', $model->id)
            ->where('processed', false)
            ->orderBy('priority', 'desc')
            ->orderBy('created_at', 'asc')
            ->get();
    }

    /**
     * Get all unprocessed changes ordered by priority
     */
    public function getAllPendingChanges(): Collection
    {
        return MsgraphPendingChange::where('processed', false)
            ->orderBy('priority', 'desc')
            ->orderBy('created_at', 'asc')
            ->get();
    }

    /**
     * Mark changes as processed for a specific model
     */
    public function markModelChangesAsProcessed($model): int
    {
        return MsgraphPendingChange::where('model_type', get_class($model))
            ->where('model_id', $model->id)
            ->where('processed', false)
            ->update([
                'processed' => true,
                'processed_at' => now()
            ]);
    }

    /**
     * Mark a specific change as processed
     */
    public function markChangeAsProcessed(MsgraphPendingChange $change): bool
    {
        return $change->update([
            'processed' => true,
            'processed_at' => now()
        ]);
    }

    /**
     * Get changes count by status
     */
    public function getChangesCount(bool $processed = false): int
    {
        return MsgraphPendingChange::where('processed', $processed)->count();
    }

    /**
     * Get recent changes (processed and unprocessed)
     */
    public function getRecentChanges(int $limit = 10): Collection
    {
        return MsgraphPendingChange::with(['user', 'model'])
            ->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
    }

    /**
     * Clean up old processed changes
     */
    public function cleanupOldProcessedChanges(int $daysOld = 30): int
    {
        return MsgraphPendingChange::where('processed', true)
            ->where('processed_at', '<', now()->subDays($daysOld))
            ->delete();
    }
}
